<commit_before>import logging
import os
import re
import serial
import struct
from threading import Lock
from serial.tools import list_ports

logger = logging.getLogger('universe')

class Maestro:
    def __init__(self, port=None, timeout=0):
        """
        :param port: The virtual port number.
        :param timeout: Timeout option for each transfer.
        """

        if port is not None:
            self.port = port
        else:
            # Determine the operating system and port strings.
            # Command port is used for USB Dual Port mode.
            # Can automatically determine from a scan.
            ports = list(list_ports.grep(r'(?i)1ffb:008b'))

            if os.name == 'nt':
                if len(ports) == 2:
                    if 'Command' in ports[0][1]:
                        self.port = ports[0][0]
                    else:
                        self.port = ports[1][0]
                else:
                    raise ConnectionError('Unable to determine the Command port automatically. Please specify.')
            else:
                if len(ports) == 2:
                    # Assuming nothing was messed with, the command port is the lower port.
                    if int(re.search(r'(\d+)$', ports[1][0]).group(0)) > int(re.search(r'(\d+)$', ports[0][0]).group(0)):
                        self.port = ports[0][0]
                    else:
                        self.port = ports[1][0]
                else:
                    raise ConnectionError('Unable to determine the Command port automatically. Please specify.')

        # Start a connection using pyserial.
        try:
            self.usb = serial.Serial(self.port)
            logger.debug('Using command port "{}".'.format(self.usb.port))
        except:
            raise ConnectionError('Unable to connect to servo controller at {}.'.format(self.port))

        # Struct objects are faster.
        self.struct = struct.Struct('<H')

        # Locks.
        self.read_lock = Lock()

    def write(self, buffer):
        """
        Send data to the Maestro.
        :param buffer: The data to send.
        """

        self.usb.write(buffer)

    def close(self):
        """
        Close the USB port.
        """

        self.usb.close()

    ##########################################
    # Begin implementation of static methods.
    ##########################################

    @staticmethod
    def endianize(value):
        """
        Endian formatting for Pololu commands.
        :param value: Integer value.
        :return: (lsb, msb)
        """
        return value & 0x7F, (value >> 7) & 0x7F

    ##########################################################
    # Begin implementation of buffer-capable compact protocol.
    ##########################################################

    def set_target(self, servo, send=True):
        """
        Move a servo to its target.
        :param servo: A servo object.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s position to {}.'.format(servo.channel, servo.target))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(servo.target)

        # Compose and send or return.
        ins = (0x84, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    def set_speed(self, servo, speed, send=True):
        """
        Set the servo speed.
        :param servo: A servo object.
        :param speed: The speed in 0.25 us / 10 ms.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s speed to {}.'.format(servo.channel, speed))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(speed)

        # Update object. However, this will not be accurate until send.
        servo.vel = speed

        # Compose and send or return.
        ins = (0x87, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    def set_acceleration(self, servo, accel, send=True):
        """
        Set the servo acceleration.
        :param servo: A servo object.
        :param accel: The acceleration in 0.25 us / 10 ms / 80 ms. See documentation for different PWM.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s acceleration to {}.'.format(servo.channel, accel))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(accel)

        # Update object. However, this will not be accurate until flush.
        servo.accel = accel

        # Compose and add to buffer.
        ins = (0x89, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    ##########################################
    # Begin implementation of bulk operations.
    ##########################################

    def get_multiple_positions(self, servos):
        """
        Get multiple positions.
        :param servos: Servo objects.
        """

        data = bytearray()
        count = len(servos)

        for servo in servos:
            data.extend((0x90, servo.channel))

        with self.read_lock:
            self.usb.write(data)
            reply = self.usb.read(size=2 * count)[0]

        for i in range(count):
            data = reply[2 * i: 2 * i + 2]
            servos[i].pwm = self.struct.unpack(data)

    def set_multiple_targets(self, servos):
        """
        Set multiple targets with one command. Faster than multiple set_target().
        Only use for contiguous blocks!
        :param servos: Servo objects.
        """

        # Count the number of targets. Required by controller.
        count = len(servos)

        # Sort.
        servos = sorted(servos, key=lambda s: s.channel)

        # Start channel
        start = servos[0].channel

        # Data header.
        data = bytearray((0x9F, count, start))

        # Iterate through all servos, appending to data as needed.
        for servo in servos:
            target = servo.deg_to_maestro(servo.target)

            # Check contiguity.
            if servo.channel != start:
                raise Exception('Channels not contiguous!')
            else:
                start += 1

            lsb, msb = self.endianize(target)
            data.extend((lsb, msb))

            # Update object.
            servo.pwm = target

        # Write.
        self.usb.write(data)

    ##########################################
    # Begin implementation of read operations.
    ##########################################

    def get_position(self, servo):
        """
        Get the position of one servo.
        :param servo: A servo object.
        """

        with self.read_lock:
            # Send command and get reply.
            self.usb.write((0x90, servo.channel))
            reply = self.usb.read(size=2)

        # Unpack data.
        pwm = self.struct.unpack(reply)[0]

        # Set servo data.
        servo.pwm = pwm

    def get_moving_state(self):
        """
        Checks if any servos are moving.
        :return: Returns True if one or more servos are moving, else False.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0x93,))
            reply = self.usb.read()

        # Check and return.
        if reply == chr(0):
            return False
        else:
            return True

    def get_errors(self):
        """
        Gets errors.
        :return: Returns an integer reprenstation of an error or None if there are no errors.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0xA1,))
            reply = self.usb.read(size=2)

        if reply:
            return self.struct.unpack(reply)[0]
        else:
            return None

    ###############################################
    # Begin implementation of accessory operations.
    ###############################################

    def set_pwm(self, time, period):
        """
        Set the PWM.
        :param time: The time parameter as specified by the documentation.
        :param period: THe period parameter as specified by the documentation.
        """

        # Use endian format suitable for Maestro.
        lsb1, msb1 = self.endianize(time)
        lsb2, msb2 = self.endianize(period)

        # Compose.
        data = (0x8A, lsb1, msb1, lsb2, msb2)

        # Write.
        self.usb.write(data)

    def go_home(self):
        """
        Return all servos to their home positions.
        """
        # Send command.
        self.usb.write((0xA2,))

    ############################################
    # Begin implementation of script operations.
    ############################################

    def stop_script(self):
        """
        Stops the running script.
        """

        # Send command.
        self.usb.write((0xA4,))

    # Restart script.
    def restart(self, subroutine, parameter=None):
        """
        Starts or restarts a script.
        :param subroutine: The subroutine number.
        :param parameter: An integer parameter to put on the stack for consumption.
        """

        # Construct command depending on parameter.
        if parameter is None:
            data = (0xA7, subroutine)
        else:
            lsb, msb = self.endianize(parameter)
            data = (0xA8, lsb, msb)

        # Send data.
        self.usb.write(data)

    def get_script_status(self):
        """
        Get a script status.
        :return: Returns True if script is running and False if it is not.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0xAE,))
            reply = self.usb.read()

        # Check and return.
        if reply == chr(0):
            return False
        else:
            return True

    ###################################################
    # Begin implementation of complex helper functions.
    ###################################################

    def end_together(self, servos, time=0, update=False):
        """
        Move all servos to their respective targets such that they arrive together.
        This will reset all accelerations to 0 and flush buffer.
        :param servos: Servo objects.
        :param time: The time in ms for the operation. Set to 0 for max speed.
        :param update: Whether of not to update servo positions.
        """

        # Update servo positions as needed.
        if update:
            self.get_multiple_positions(servos)

        # Max speed.
        if time == 0:
            time = max([abs(servo.target - servo.pwm) / servo.max_vel * 10 for servo in servos])

        # Faster send.
        buffer = bytearray()

        # Compute and set the velocity for every servo.
        for servo in servos:
            # Set acceleration to zero.
            ins = self.set_acceleration(servo, 0, send=False)
            buffer.extend(ins)

            # Compute velocity as a change in 0.25us PWM / 10ms.
            delta = abs(servo.target - servo.pwm)
            vel = int(round(delta / time * 10))

            # Set velocity.
            ins = self.set_speed(servo, vel, send=False)
            buffer.extend(ins)

        # Send data.
        self.write(buffer)

        # Synchronize instructions.
        buffer = bytearray()

        # Move all servos to their respective targets.
        for servo in servos:
            ins = self.set_target(servo, send=False)
            buffer.extend(ins)

        # Send to execute move.
        self.write(buffer)
<commit_msg>timeout check<commit_after>import logging
import os
import re
import serial
from serial import SerialTimeoutException
import struct
from threading import Lock
from serial.tools import list_ports

logger = logging.getLogger('universe')

class Maestro:
    """
    Implementation of the controller for Pololu Mini Maestro Controller.
    This class communicates with only one maestro on the virtual command port.

    This implementation is thread-safe.
    However, a servo can only belong to at most one thread.
    Having a servo in multiple threads will cause errors.
    """

    def __init__(self, port=None, timeout=2):
        """
        :param port: The virtual port number.
        :param timeout: Timeout option for each transfer.
        """

        if port is not None:
            self.port = port
        else:
            # Determine the operating system and port strings.
            # Command port is used for USB Dual Port mode.
            # Can automatically determine from a scan.
            ports = list(list_ports.grep(r'(?i)1ffb:008b'))

            if os.name == 'nt':
                if len(ports) == 2:
                    if 'Command' in ports[0][1]:
                        self.port = ports[0][0]
                    else:
                        self.port = ports[1][0]
                else:
                    raise ConnectionError('Unable to determine the Command port automatically. Please specify.')
            else:
                if len(ports) == 2:
                    # Assuming nothing was messed with, the command port is the lower port.
                    if int(re.search(r'(\d+)$', ports[1][0]).group(0)) > int(re.search(r'(\d+)$', ports[0][0]).group(0)):
                        self.port = ports[0][0]
                    else:
                        self.port = ports[1][0]
                else:
                    raise ConnectionError('Unable to determine the Command port automatically. Please specify.')

        # Start a connection using pyserial.
        try:
            self.usb = serial.Serial(self.port, timeout=timeout, write_timeout=timeout)
            logger.debug('Using command port "{}".'.format(self.usb.port))
        except:
            raise ConnectionError('Unable to connect to servo controller at {}.'.format(self.port))

        # Struct objects are faster.
        self.struct = struct.Struct('<H')

        # Locks.
        self.read_lock = Lock()

        # Exceptions.
        self.read_error = SerialTimeoutException('Read timeout')

    def write(self, buffer):
        """
        Send data to the Maestro.
        :param buffer: The data to send.
        """

        self.usb.write(buffer)

    def close(self):
        """
        Close the USB port.
        """

        self.usb.close()

    ##########################################
    # Begin implementation of static methods.
    ##########################################

    @staticmethod
    def endianize(value):
        """
        Endian formatting for Pololu commands.
        :param value: Integer value.
        :return: (lsb, msb)
        """
        return value & 0x7F, (value >> 7) & 0x7F

    ##########################################################
    # Begin implementation of buffer-capable compact protocol.
    ##########################################################

    def set_target(self, servo, send=True):
        """
        Move a servo to its target.
        :param servo: A servo object.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s position to {}.'.format(servo.channel, servo.target))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(servo.target)

        # Compose and send or return.
        ins = (0x84, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    def set_speed(self, servo, speed, send=True):
        """
        Set the servo speed.
        :param servo: A servo object.
        :param speed: The speed in 0.25 us / 10 ms.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s speed to {}.'.format(servo.channel, speed))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(speed)

        # Update object. However, this will not be accurate until send.
        servo.vel = speed

        # Compose and send or return.
        ins = (0x87, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    def set_acceleration(self, servo, accel, send=True):
        """
        Set the servo acceleration.
        :param servo: A servo object.
        :param accel: The acceleration in 0.25 us / 10 ms / 80 ms. See documentation for different PWM.
        :param send: Whether or not to send instruction immediately.
        :return: The instruction tuple.
        """

        # Logging.
        logger.debug('Setting servo {}\'s acceleration to {}.'.format(servo.channel, accel))

        # Use endian format suitable for Maestro.
        lsb, msb = self.endianize(accel)

        # Update object. However, this will not be accurate until flush.
        servo.accel = accel

        # Compose and add to buffer.
        ins = (0x89, servo.channel, lsb, msb)

        if send:
            self.usb.write(ins)

        return ins

    ##########################################
    # Begin implementation of bulk operations.
    ##########################################

    def get_multiple_positions(self, servos):
        """
        Get multiple positions.
        :param servos: Servo objects.
        """

        data = bytearray()
        count = len(servos)
        size = 2 * count

        for servo in servos:
            data.extend((0x90, servo.channel))

        with self.read_lock:
            self.usb.write(data)
            reply = self.usb.read(size=size)[0]

        if len(reply) != size:
            raise self.read_error

        for i in range(count):
            data = reply[2 * i: 2 * i + 2]
            servos[i].pwm = self.struct.unpack(data)

    def set_multiple_targets(self, servos):
        """
        Set multiple targets with one command. Faster than multiple set_target().
        Only use for contiguous blocks!
        :param servos: Servo objects.
        """

        # Count the number of targets. Required by controller.
        count = len(servos)

        # Sort.
        servos = sorted(servos, key=lambda s: s.channel)

        # Start channel
        start = servos[0].channel

        # Data header.
        data = bytearray((0x9F, count, start))

        # Iterate through all servos, appending to data as needed.
        for servo in servos:
            target = servo.deg_to_maestro(servo.target)

            # Check contiguity.
            if servo.channel != start:
                raise Exception('Channels not contiguous!')
            else:
                start += 1

            lsb, msb = self.endianize(target)
            data.extend((lsb, msb))

            # Update object.
            servo.pwm = target

        # Write.
        self.usb.write(data)

    ##########################################
    # Begin implementation of read operations.
    ##########################################

    def get_position(self, servo):
        """
        Get the position of one servo.
        :param servo: A servo object.
        """

        with self.read_lock:
            # Send command and get reply.
            self.usb.write((0x90, servo.channel))
            reply = self.usb.read(size=2)

        if len(reply) != 2:
            raise self.read_error

        # Unpack data.
        pwm = self.struct.unpack(reply)[0]

        # Set servo data.
        servo.pwm = pwm

    def get_moving_state(self):
        """
        Checks if any servos are moving.
        :return: Returns True if one or more servos are moving, else False.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0x93,))
            reply = self.usb.read()

        if len(reply) != 1:
            raise self.read_error

        # Check and return.
        if reply == chr(0):
            return False
        else:
            return True

    def get_errors(self):
        """
        Gets errors.
        :return: Returns an integer reprenstation of an error or None if there are no errors.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0xA1,))
            reply = self.usb.read(size=2)

        if len(reply) != 2:
            raise self.read_error

        if reply:
            return self.struct.unpack(reply)[0]
        else:
            return None

    ###############################################
    # Begin implementation of accessory operations.
    ###############################################

    def set_pwm(self, time, period):
        """
        Set the PWM.
        :param time: The time parameter as specified by the documentation.
        :param period: THe period parameter as specified by the documentation.
        """

        # Use endian format suitable for Maestro.
        lsb1, msb1 = self.endianize(time)
        lsb2, msb2 = self.endianize(period)

        # Compose.
        data = (0x8A, lsb1, msb1, lsb2, msb2)

        # Write.
        self.usb.write(data)

    def go_home(self):
        """
        Return all servos to their home positions.
        """
        # Send command.
        self.usb.write((0xA2,))

    ############################################
    # Begin implementation of script operations.
    ############################################

    def stop_script(self):
        """
        Stops the running script.
        """

        # Send command.
        self.usb.write((0xA4,))

    # Restart script.
    def restart(self, subroutine, parameter=None):
        """
        Starts or restarts a script.
        :param subroutine: The subroutine number.
        :param parameter: An integer parameter to put on the stack for consumption.
        """

        # Construct command depending on parameter.
        if parameter is None:
            data = (0xA7, subroutine)
        else:
            lsb, msb = self.endianize(parameter)
            data = (0xA8, lsb, msb)

        # Send data.
        self.usb.write(data)

    def get_script_status(self):
        """
        Get a script status.
        :return: Returns True if script is running and False if it is not.
        """

        with self.read_lock:
            # Send command and receive.
            self.usb.write((0xAE,))
            reply = self.usb.read()

        if len(reply) != 1:
            raise self.read_error

        # Check and return.
        if reply == chr(0):
            return False
        else:
            return True

    ###################################################
    # Begin implementation of complex helper functions.
    ###################################################

    def end_together(self, servos, time=0, update=False):
        """
        Move all servos to their respective targets such that they arrive together.
        This will reset all accelerations to 0 and flush buffer.
        :param servos: Servo objects.
        :param time: The time in ms for the operation. Set to 0 for max speed.
        :param update: Whether of not to update servo positions.
        """

        # Update servo positions as needed.
        if update:
            self.get_multiple_positions(servos)

        # Max speed.
        if time == 0:
            time = max([abs(servo.target - servo.pwm) / servo.max_vel * 10 for servo in servos])

        # Faster send.
        buffer = bytearray()

        # Compute and set the velocity for every servo.
        for servo in servos:
            # Set acceleration to zero.
            ins = self.set_acceleration(servo, 0, send=False)
            buffer.extend(ins)

            # Compute velocity as a change in 0.25us PWM / 10ms.
            delta = abs(servo.target - servo.pwm)
            vel = int(round(delta / time * 10))

            # Set velocity.
            ins = self.set_speed(servo, vel, send=False)
            buffer.extend(ins)

        # Send data.
        self.write(buffer)

        # Synchronize instructions.
        buffer = bytearray()

        # Move all servos to their respective targets.
        for servo in servos:
            ins = self.set_target(servo, send=False)
            buffer.extend(ins)

        # Send to execute move.
        self.write(buffer)
<|endoftext|>


<commit_before># Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable-all

from unittest import TestCase
from unittest.mock import patch

from opentelemetry.configuration import Configuration

class TestConfiguration(TestCase):

    # These calls reset the attributes of the Configuration class so that each
    # test is executed in the same conditions.
    def setUp(self) -> None:
        Configuration._reset()

    def test_singleton(self) -> None:
        self.assertIsInstance(Configuration(), Configuration)
        self.assertIs(Configuration(), Configuration())

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_METER_PROVIDER": "meter_provider",
            "OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider",
            "OTEL_OThER": "other",
            "OTEL_OTHER_7": "other_7",
            "OPENTELEMETRY_PTHON_TRACEX_PROVIDER": "tracex_provider",
        },
    )
    def test_environment_variables(self) -> None:
        self.assertEqual(
            Configuration().METER_PROVIDER, "meter_provider"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().TRACER_PROVIDER, "tracer_provider"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().OThER, "other"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().OTHER_7, "other_7"
        )  # pylint: disable=no-member
        self.assertIsNone(Configuration().TRACEX_PROVIDER)

    @patch.dict(
        "os.environ",  # type: ignore
        {"OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider"},
    )
    def test_property(self) -> None:
        with self.assertRaises(AttributeError):
            Configuration().TRACER_PROVIDER = "new_tracer_provider"

    def test_set_once(self) -> None:

        Configuration().XYZ = "xyz"

        with self.assertRaises(AttributeError):
            Configuration().XYZ = "abc"  # pylint: disable=assigning-non-slot

    def test_getattr(self) -> None:
        # literal access
        self.assertIsNone(Configuration().XYZ)

        # dynamic access
        self.assertIsNone(getattr(Configuration(), "XYZ"))
        self.assertIsNone(Configuration().get("XYZ", None))

    def test_reset(self) -> None:
        environ_patcher = patch.dict(
            "os.environ", {"OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider"},
        )

        environ_patcher.start()

        self.assertEqual(
            Configuration().TRACER_PROVIDER, "tracer_provider"
        )  # pylint: disable=no-member

        environ_patcher.stop()

        Configuration._reset()

        self.assertIsNone(
            Configuration().TRACER_PROVIDER
        )  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {"OTEL_TRUE": "True", "OTEL_FALSE": "False"},
    )
    def test_boolean(self) -> None:
        self.assertIsInstance(
            Configuration().TRUE, bool
        )  # pylint: disable=no-member
        self.assertIsInstance(
            Configuration().FALSE, bool
        )  # pylint: disable=no-member
        self.assertTrue(Configuration().TRUE)  # pylint: disable=no-member
        self.assertFalse(Configuration().FALSE)  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_POSITIVE_INTEGER": "123",
            "OTEL_NEGATIVE_INTEGER": "-123",
            "OTEL_NON_INTEGER": "-12z3",
        },
    )
    def test_integer(self) -> None:
        # pylint: disable=no-member
        self.assertIsInstance(Configuration().POSITIVE_INTEGER, int)
        self.assertEqual(Configuration().POSITIVE_INTEGER, 123)
        self.assertIsInstance(Configuration().NEGATIVE_INTEGER, int)
        self.assertEqual(Configuration().NEGATIVE_INTEGER, -123)
        self.assertEqual(Configuration().NON_INTEGER, "-12z3")

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_POSITIVE_FLOAT": "123.123",
            "OTEL_NEGATIVE_FLOAT": "-123.123",
            "OTEL_NON_FLOAT": "-12z3.123",
        },
    )
    def test_float(self) -> None:
        self.assertEqual(
            Configuration().POSITIVE_FLOAT, 123.123
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().NEGATIVE_FLOAT, -123.123
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().NON_FLOAT, "-12z3.123"
        )  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_WEBFRAMEWORK_TRACED_REQUEST_ATTRS": "content_type,keep_alive",
        },
    )
    def test_traced_request_attrs(self) -> None:
        cfg = Configuration()
        request_attrs = cfg._traced_request_attrs("webframework")
        self.assertEqual(len(request_attrs), 2)
        self.assertIn("content_type", request_attrs)
        self.assertIn("keep_alive", request_attrs)
        self.assertNotIn("authorization", request_attrs)

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_WEBFRAMEWORK_EXCLUDED_URLS": "/healthzz,path,/issues/.*/view",
        },
    )
    def test_excluded_urls(self) -> None:
        cfg = Configuration()
        excluded_urls = cfg._excluded_urls("webframework")
        self.assertTrue(excluded_urls.url_disabled("/healthzz"))
        self.assertTrue(excluded_urls.url_disabled("/path"))
        self.assertTrue(excluded_urls.url_disabled("/issues/123/view"))
        self.assertFalse(excluded_urls.url_disabled("/issues"))
        self.assertFalse(excluded_urls.url_disabled("/hello"))
<commit_msg>Use uppercase if testing in windows (#1484)<commit_after># Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable-all

from sys import platform
from unittest import TestCase
from unittest.mock import patch

from opentelemetry.configuration import Configuration

class TestConfiguration(TestCase):

    # These calls reset the attributes of the Configuration class so that each
    # test is executed in the same conditions.
    def setUp(self) -> None:
        Configuration._reset()

    def test_singleton(self) -> None:
        self.assertIsInstance(Configuration(), Configuration)
        self.assertIs(Configuration(), Configuration())

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_METER_PROVIDER": "meter_provider",
            "OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider",
            "OTEL_OTHER" if platform == "windows" else "OTEL_OThER": "other",
            "OTEL_OTHER_7": "other_7",
            "OPENTELEMETRY_PTHON_TRACEX_PROVIDER": "tracex_provider",
        },
    )
    def test_environment_variables(self) -> None:
        self.assertEqual(
            Configuration().METER_PROVIDER, "meter_provider"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().TRACER_PROVIDER, "tracer_provider"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().OThER, "other"
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().OTHER_7, "other_7"
        )  # pylint: disable=no-member
        self.assertIsNone(Configuration().TRACEX_PROVIDER)

    @patch.dict(
        "os.environ",  # type: ignore
        {"OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider"},
    )
    def test_property(self) -> None:
        with self.assertRaises(AttributeError):
            Configuration().TRACER_PROVIDER = "new_tracer_provider"

    def test_set_once(self) -> None:

        Configuration().XYZ = "xyz"

        with self.assertRaises(AttributeError):
            Configuration().XYZ = "abc"  # pylint: disable=assigning-non-slot

    def test_getattr(self) -> None:
        # literal access
        self.assertIsNone(Configuration().XYZ)

        # dynamic access
        self.assertIsNone(getattr(Configuration(), "XYZ"))
        self.assertIsNone(Configuration().get("XYZ", None))

    def test_reset(self) -> None:
        environ_patcher = patch.dict(
            "os.environ", {"OTEL_PYTHON_TRACER_PROVIDER": "tracer_provider"},
        )

        environ_patcher.start()

        self.assertEqual(
            Configuration().TRACER_PROVIDER, "tracer_provider"
        )  # pylint: disable=no-member

        environ_patcher.stop()

        Configuration._reset()

        self.assertIsNone(
            Configuration().TRACER_PROVIDER
        )  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {"OTEL_TRUE": "True", "OTEL_FALSE": "False"},
    )
    def test_boolean(self) -> None:
        self.assertIsInstance(
            Configuration().TRUE, bool
        )  # pylint: disable=no-member
        self.assertIsInstance(
            Configuration().FALSE, bool
        )  # pylint: disable=no-member
        self.assertTrue(Configuration().TRUE)  # pylint: disable=no-member
        self.assertFalse(Configuration().FALSE)  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_POSITIVE_INTEGER": "123",
            "OTEL_NEGATIVE_INTEGER": "-123",
            "OTEL_NON_INTEGER": "-12z3",
        },
    )
    def test_integer(self) -> None:
        # pylint: disable=no-member
        self.assertIsInstance(Configuration().POSITIVE_INTEGER, int)
        self.assertEqual(Configuration().POSITIVE_INTEGER, 123)
        self.assertIsInstance(Configuration().NEGATIVE_INTEGER, int)
        self.assertEqual(Configuration().NEGATIVE_INTEGER, -123)
        self.assertEqual(Configuration().NON_INTEGER, "-12z3")

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_POSITIVE_FLOAT": "123.123",
            "OTEL_NEGATIVE_FLOAT": "-123.123",
            "OTEL_NON_FLOAT": "-12z3.123",
        },
    )
    def test_float(self) -> None:
        self.assertEqual(
            Configuration().POSITIVE_FLOAT, 123.123
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().NEGATIVE_FLOAT, -123.123
        )  # pylint: disable=no-member
        self.assertEqual(
            Configuration().NON_FLOAT, "-12z3.123"
        )  # pylint: disable=no-member

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_WEBFRAMEWORK_TRACED_REQUEST_ATTRS": "content_type,keep_alive",
        },
    )
    def test_traced_request_attrs(self) -> None:
        cfg = Configuration()
        request_attrs = cfg._traced_request_attrs("webframework")
        self.assertEqual(len(request_attrs), 2)
        self.assertIn("content_type", request_attrs)
        self.assertIn("keep_alive", request_attrs)
        self.assertNotIn("authorization", request_attrs)

    @patch.dict(
        "os.environ",  # type: ignore
        {
            "OTEL_PYTHON_WEBFRAMEWORK_EXCLUDED_URLS": "/healthzz,path,/issues/.*/view",
        },
    )
    def test_excluded_urls(self) -> None:
        cfg = Configuration()
        excluded_urls = cfg._excluded_urls("webframework")
        self.assertTrue(excluded_urls.url_disabled("/healthzz"))
        self.assertTrue(excluded_urls.url_disabled("/path"))
        self.assertTrue(excluded_urls.url_disabled("/issues/123/view"))
        self.assertFalse(excluded_urls.url_disabled("/issues"))
        self.assertFalse(excluded_urls.url_disabled("/hello"))
<|endoftext|>


<commit_before>from moksha.connector import IConnector, ICall, IQuery, ParamFilter, ISearch
from pylons import config

import os
import sys
import yum

class YumConnector(IConnector, ICall, ISearch, IQuery):
    _method_paths = {}
    _query_paths = {}

    def __init__(self, environ=None, request=None):
        super(YumConnector, self).__init__(environ, request)
        self._yum_client = yum.YumBase()
        self._yum_client.conf.fn = self._conf_file
        self._yum_client.conf.cache = 1

    # IConnector
    @classmethod
    def register(cls):
        cls._conf_file = config.get('fedoracommunity.connector.yum.conf',
                                   '/etc/yum/yum.conf')

        cls.register_search_packages()

    def introspect(self):
        # FIXME: return introspection data
        return None

    # ISearch
    @classmethod
    def register_search_packages(cls):
        path = cls.register_search_path(
                      'search_packages',
                      cls.search_packages,
                      primary_key_col = 'name',
                      default_sort_col = 'name',
                      default_sort_order = -1,
                      can_paginate = True)

        path.register_column('name',
                        default_visible = True,
                        can_sort = False,
                        can_filter_wildcards = False)

        path.register_column('summary',
                        default_visible = True,
                        can_sort = False,
                        can_filter_wildcards = False)

        path.register_column('description',
                             default_visible = True,
                             can_sort = False,
                             can_filter_wildcards = False)

        # cache the column names so we don't have to edit them in two places
        cls._package_search_field_list = []
        for col in path['columns']:
            cls._package_search_field_list.append(col)

    def search_packages(self, search_term):
        searchlist = self._package_search_field_list

        search_term = search_term.split()

        search = self._yum_client.searchGenerator(searchlist, search_term, showdups = False)
        results = []
        seen = set()
        for (pkg, values) in search:
            if pkg.name not in seen:
                row = {}
                for s in searchlist:
                    row[s] = pkg.__getattribute__(s)

                results.append(row)
                seen.add(pkg.name)

        self._yum_client.close()
        return results
<commit_msg>move to calling doConfigSetup instead of setting teh config file manually<commit_after>from moksha.connector import IConnector, ICall, IQuery, ParamFilter, ISearch
from pylons import config

import os
import sys
import yum

class YumConnector(IConnector, ICall, ISearch, IQuery):
    _method_paths = {}
    _query_paths = {}

    def __init__(self, environ=None, request=None):
        super(YumConnector, self).__init__(environ, request)
        self._yum_client = yum.YumBase()
        self._yum_client.doConfigSetup(fn = self._conf_file)

    # IConnector
    @classmethod
    def register(cls):
        cls._conf_file = config.get('fedoracommunity.connector.yum.conf',
                                   '/etc/yum/yum.conf')

        cls.register_search_packages()

    def introspect(self):
        # FIXME: return introspection data
        return None

    # ISearch
    @classmethod
    def register_search_packages(cls):
        path = cls.register_search_path(
                      'search_packages',
                      cls.search_packages,
                      primary_key_col = 'name',
                      default_sort_col = 'name',
                      default_sort_order = -1,
                      can_paginate = True)

        path.register_column('name',
                        default_visible = True,
                        can_sort = False,
                        can_filter_wildcards = False)

        path.register_column('summary',
                        default_visible = True,
                        can_sort = False,
                        can_filter_wildcards = False)

        path.register_column('description',
                             default_visible = True,
                             can_sort = False,
                             can_filter_wildcards = False)

        # cache the column names so we don't have to edit them in two places
        cls._package_search_field_list = []
        for col in path['columns']:
            cls._package_search_field_list.append(col)

    def search_packages(self, search_term):
        searchlist = self._package_search_field_list

        search_term = search_term.split()

        search = self._yum_client.searchGenerator(searchlist, search_term, showdups = False)
        results = []
        seen = set()
        for (pkg, values) in search:
            if pkg.name not in seen:
                row = {}
                for s in searchlist:
                    row[s] = pkg.__getattribute__(s)

                results.append(row)
                seen.add(pkg.name)

        self._yum_client.close()
        return results
<|endoftext|>


<commit_before>import uuid

class Action(object):
    """
    Base class for actions
    Fabio Manganiello, 2015 <blacklight86@gmail.com>
    """

    def __init__(self, **kwargs):
        vars(self).update(kwargs)

        # A unique ID that identifies the action along its lifecycle
        self.__action_id = uuid.uuid4()

    def link(self, event):
        """
        Create a link between the action and the event processed by the engine
        that triggered the action.
        """

        # The event that triggered the action
        self.event = event

    def on_event(self, event):
        """
        Execute the logic of the action.
        To be implemented by the derived classes.
        """
        raise NotImplementedError()

    def run(self):
        """
        Shortcut for on_event invoked after the action has been linked to an
        event by the engine,
        """
        self.on_event(self.event)

# vim:sw=4:ts=4:et:

<commit_msg>Action refactoring and documentation.<commit_after>import enum
import time
import uuid

class ActionState(enum.Enum):
    """
    Enum that maps the states of an action lifecycle
    Fabio Manganiello, 2015 <blacklight86@gmail.com>
    """

    create = 'Create'
    link = 'Link'
    start = 'Start'
    end = 'End'
    kill = 'Kill'

class Action(object):
    """
    Base class for actions
    Fabio Manganiello, 2015 <blacklight86@gmail.com>
    """

    def __init__(self, **kwargs):
        vars(self).update(kwargs)

        # A unique ID that identifies the action along its lifecycle
        self.__action_id = uuid.uuid4()

        # Map of the timestamps for the states of the action
        self.__timestamps = dict(map(lambda state: (state, None), [state for state in ActionState]))
        self.__timestamps[ActionState.create] = time.time()

    def link(self, event):
        """
        Create a link between the action and the event processed by the engine
        that triggered the action.
        """

        # The event that triggered the action
        self.event = event
        self.__timestamps[ActionState.link] = time.time()

    def on_event(self, event):
        """
        Execute the logic of the action.
        To be implemented by the derived classes.

        NOTE: An action should be run only be the engine, and only after having
        it linked to an event. Therefore, if you ever want to manually run an
        action outside of the engine context, you should first link() it to the
        event and then execute run(), so all the states of the action can be
        correctly tracked. on_event should be used directly only in unit tests.
        """

        # Implement this in the derived classes, but always execute the action
        # through run()
        raise NotImplementedError()

    def run(self):
        """
        Shortcut for on_event invoked after the action has been linked to an
        event by the engine,
        """
        self.__timestamps[ActionState.start] = time.time()
        self.on_event(self.event)
        self.__timestamps[ActionState.end] = time.time()

# vim:sw=4:ts=4:et:

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# pylint: disable=missing-docstring, invalid-name
##############################################################################
#
# Copyright (c) 2011, Martín Raúl Villalba
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
##############################################################################

from __future__ import division, absolute_import, print_function, unicode_literals

from threading import Lock

# USB1 driver uses a USB<->Serial bridge
from serial import Serial, SerialException, SerialTimeoutException
# USB2 driver uses direct USB connection. Requires PyUSB
from usb.control import get_interface
from usb.core import USBError, find as findDeviceUSB
from usb.util import (find_descriptor, claim_interface, release_interface,
                      dispose_resources, endpoint_direction, ENDPOINT_OUT, ENDPOINT_IN)

from ant.core.exceptions import DriverError

class Driver(object):
    def __init__(self, log=None, debug=False):
        self.debug = debug
        self.log = log
        self._lock = Lock()

    def open(self):
        with self._lock:
            if self._opened:
                raise DriverError("Could not open device (already open).")

            self._open()
            if self.log:
                self.log.logOpen()

    @property
    def opened(self):
        with self._lock:
            return self._opened

    def close(self):
        with self._lock:
            if not self._opened:
                raise DriverError("Could not close device (not open).")

            self._close()
            if self.log:
                self.log.logClose()

    def read(self, count):
        if count <= 0:
            raise DriverError("Could not read from device (zero request).")
        if not self.opened:
            raise DriverError("Could not read from device (not open).")

        data = self._read(count)

        with self._lock:
            if self.log:
                self.log.logRead(data)
            if self.debug:
                self._dump(data, 'R')
        return data

    def write(self, msg):
        if not self.opened:
            raise DriverError("Could not write to device (not open).")

        data = msg.encode()
        ret = self._write(data)

        with self._lock:
            if self.debug:
                self._dump(str(data), 'W')
            if self.log:
                self.log.logWrite(data[0:ret])
        return ret

    @staticmethod
    def _dump(data, title):
        if len(data) == 0:
            return
        print('%s:  ' % title, *('%02X' % ord(byte) for byte in data))

    @property
    def _opened(self):
        raise NotImplementedError()

    def _open(self):
        raise NotImplementedError()

    def _close(self):
        raise NotImplementedError()

    def _read(self, count):
        raise NotImplementedError()

    def _write(self, data):
        raise NotImplementedError()

class USB1Driver(Driver):
    def __init__(self, device, baudRate=115200, log=None, debug=False):
        super(USB1Driver, self).__init__(log=log, debug=debug)
        self.device = device
        self.baud = baudRate
        self._serial = None

    def _open(self):
        try:
            dev = Serial(self.device, self.baud)
        except SerialException as e:
            raise DriverError(str(e))

        if not dev.isOpen():
            raise DriverError("Could not open device")

        self._serial = dev
        dev.timeout = 0.01

    @property
    def _opened(self):
        return self._serial is not None

    def _close(self):
        self._serial.close()

    def _read(self, count):
        return self._serial.read(count)

    def _write(self, data):
        try:
            count = self._serial.write(data)
            self._serial.flush()
        except SerialTimeoutException as e:
            raise DriverError(str(e))

        return count

class USB2Driver(Driver):

    def __init__(self, idVendor=0x0fcf, idProduct=0x1008, log=None, debug=False):
        super(USB2Driver, self).__init__(log=log, debug=debug)
        self.idVendor = idVendor
        self.idProduct = idProduct

        self._epOut = None
        self._epIn = None
        self._dev = None
        self._intNum = None

    def _open(self):
        # Most of this is straight from the PyUSB example documentation
        dev = findDeviceUSB(idVendor=self.idVendor, idProduct=self.idProduct)

        if dev is None:
            raise DriverError("Could not open device (not found)")

        # make sure the kernel driver is not active
        if dev.is_kernel_driver_active(0):
            try:
                dev.detach_kernel_driver(0)
            except USBError as e:
                exit("could not detach kernel driver: {}".format(e))

        dev.set_configuration()
        cfg = dev.get_active_configuration()
        interfaceNumber = cfg[(0, 0)].bInterfaceNumber

        intf = find_descriptor(cfg,
            bInterfaceNumber=interfaceNumber,
            bAlternateSetting=get_interface(dev, interfaceNumber)
        )

        claim_interface(dev, interfaceNumber)
        epOut = find_descriptor(intf, custom_match= \
            lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_OUT
        )
        assert epOut is not None

        ep_in = find_descriptor(intf, custom_match= \
            lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_IN
        )
        assert ep_in is not None

        self._epOut = epOut
        self._epIn = ep_in
        self._dev = dev
        self._intNum = interfaceNumber

    @property
    def _opened(self):
        return self._dev is not None

    def _close(self):
        dev = self._dev
        release_interface(dev, self._intNum)
        dispose_resources(dev)
        self._dev = None
        # release 'Endpoints' objects for prevent undeleted 'Device' resource
        self._epOut = self._epIn = None

    def _read(self, count):
        return self._epIn.read(count).tostring()

    def _write(self, data):
        return self._epOut.write(data)
<commit_msg>Revert "shorter debug messages"<commit_after># -*- coding: utf-8 -*-
# pylint: disable=missing-docstring, invalid-name
##############################################################################
#
# Copyright (c) 2011, Martín Raúl Villalba
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
##############################################################################

from __future__ import division, absolute_import, print_function, unicode_literals

from threading import Lock

# USB1 driver uses a USB<->Serial bridge
from serial import Serial, SerialException, SerialTimeoutException
# USB2 driver uses direct USB connection. Requires PyUSB
from usb.control import get_interface
from usb.core import USBError, find as findDeviceUSB
from usb.util import (find_descriptor, claim_interface, release_interface,
                      dispose_resources, endpoint_direction, ENDPOINT_OUT, ENDPOINT_IN)

from ant.core.exceptions import DriverError

class Driver(object):
    def __init__(self, log=None, debug=False):
        self.debug = debug
        self.log = log
        self._lock = Lock()

    def open(self):
        with self._lock:
            if self._opened:
                raise DriverError("Could not open device (already open).")

            self._open()
            if self.log:
                self.log.logOpen()

    @property
    def opened(self):
        with self._lock:
            return self._opened

    def close(self):
        with self._lock:
            if not self._opened:
                raise DriverError("Could not close device (not open).")

            self._close()
            if self.log:
                self.log.logClose()

    def read(self, count):
        if count <= 0:
            raise DriverError("Could not read from device (zero request).")
        if not self.opened:
            raise DriverError("Could not read from device (not open).")

        data = self._read(count)

        with self._lock:
            if self.log:
                self.log.logRead(data)
            if self.debug:
                self._dump(data, 'READ')
        return data

    def write(self, msg):
        if not self.opened:
            raise DriverError("Could not write to device (not open).")

        data = msg.encode()
        ret = self._write(data)

        with self._lock:
            if self.debug:
                self._dump(str(data), 'WRITE')
            if self.log:
                self.log.logWrite(data[0:ret])
        return ret

    @staticmethod
    def _dump(data, title):
        if len(data) == 0:
            return

        print("========== [%s] ==========" % title)

        line, length = 0, 8
        while data:
            line += length
            print('%04X' % line, *('%02X' % ord(byte) for byte in data[:length]))
            data = data[length:]

        print()

    @property
    def _opened(self):
        raise NotImplementedError()

    def _open(self):
        raise NotImplementedError()

    def _close(self):
        raise NotImplementedError()

    def _read(self, count):
        raise NotImplementedError()

    def _write(self, data):
        raise NotImplementedError()

class USB1Driver(Driver):
    def __init__(self, device, baudRate=115200, log=None, debug=False):
        super(USB1Driver, self).__init__(log=log, debug=debug)
        self.device = device
        self.baud = baudRate
        self._serial = None

    def _open(self):
        try:
            dev = Serial(self.device, self.baud)
        except SerialException as e:
            raise DriverError(str(e))

        if not dev.isOpen():
            raise DriverError("Could not open device")

        self._serial = dev
        dev.timeout = 0.01

    @property
    def _opened(self):
        return self._serial is not None

    def _close(self):
        self._serial.close()

    def _read(self, count):
        return self._serial.read(count)

    def _write(self, data):
        try:
            count = self._serial.write(data)
            self._serial.flush()
        except SerialTimeoutException as e:
            raise DriverError(str(e))

        return count

class USB2Driver(Driver):

    def __init__(self, idVendor=0x0fcf, idProduct=0x1008, log=None, debug=False):
        super(USB2Driver, self).__init__(log=log, debug=debug)
        self.idVendor = idVendor
        self.idProduct = idProduct

        self._epOut = None
        self._epIn = None
        self._dev = None
        self._intNum = None

    def _open(self):
        # Most of this is straight from the PyUSB example documentation
        dev = findDeviceUSB(idVendor=self.idVendor, idProduct=self.idProduct)

        if dev is None:
            raise DriverError("Could not open device (not found)")

        # make sure the kernel driver is not active
        if dev.is_kernel_driver_active(0):
            try:
                dev.detach_kernel_driver(0)
            except USBError as e:
                exit("could not detach kernel driver: {}".format(e))

        dev.set_configuration()
        cfg = dev.get_active_configuration()
        interfaceNumber = cfg[(0, 0)].bInterfaceNumber

        intf = find_descriptor(cfg,
            bInterfaceNumber=interfaceNumber,
            bAlternateSetting=get_interface(dev, interfaceNumber)
        )

        claim_interface(dev, interfaceNumber)
        epOut = find_descriptor(intf, custom_match= \
            lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_OUT
        )
        assert epOut is not None

        ep_in = find_descriptor(intf, custom_match= \
            lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_IN
        )
        assert ep_in is not None

        self._epOut = epOut
        self._epIn = ep_in
        self._dev = dev
        self._intNum = interfaceNumber

    @property
    def _opened(self):
        return self._dev is not None

    def _close(self):
        dev = self._dev
        release_interface(dev, self._intNum)
        dispose_resources(dev)
        self._dev = None
        # release 'Endpoints' objects for prevent undeleted 'Device' resource
        self._epOut = self._epIn = None

    def _read(self, count):
        return self._epIn.read(count).tostring()

    def _write(self, data):
        return self._epOut.write(data)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from specparser import get_settings_from_file
import csv

def sniff_csv(csvfile):
    csv_sniffer = csv.Sniffer()
    buf = csvfile.read(1024)
    dialect = csv_sniffer.sniff(buf)
    has_header = csv_sniffer.has_header(buf)
    csvfile.seek(0)
    return dialect, has_header

def make_header(num):
    header = []
    for i in range(num):
      header.append('c'+str(i))
    return header

def get_header_data(filename):
    try:
        with open(filename, "rb") as f:
            dialect, has_header = sniff_csv(f)
            data = list(csv.reader(f, dialect))
            if has_header:
                data_header = data[0]
                data = data[1:]
                return True,data_header,data
            else:
                return False,None,data
    except:
        with open(filename,"rb") as f:
            data_header_len = 0
            data = []
            while 1:
                line = f.readline()
                if not line :
                    break
                data_header_len=len(line.split(','))
                data.append(line.rstrip('\n').split(','))
            return False,None,data

def main():
    settings = get_settings_from_file("spec.json")
    print(settings)

    # TODO: Add your code here

    left_part = get_header_data(settings.Input.x)
    right_part = get_header_data(settings.Input.y)

    file_merged = open(settings.Output.merged_file,"wb")
    writer = csv.writer(file_merged)

    if(left_part[0] and right_part[0] ):
        left_part[1].extend(right_part[1])
        writer.writerow(left_part[1])
    if(len(left_part[2]) != len(right_part[2])):
        raise Exception

    for i in range(len(left_part[2])):
        l = left_part[2][i]
        r = right_part[2][i]
        l.extend(r)
        writer.writerow(l)
    file_merged.close()

    print("Done")

if __name__ == "__main__":
    main()
<commit_msg>bug fix on one column csv manipulation<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from specparser import get_settings_from_file
import csv

def sniff_csv(csvfile):
    csv_sniffer = csv.Sniffer()
    buf = csvfile.read(1024)
    dialect = csv_sniffer.sniff(buf)
    has_header = csv_sniffer.has_header(buf)
    csvfile.seek(0)
    return dialect, has_header

def make_header(num):
    header = []
    for i in range(num):
      header.append('c'+str(i))
    return header

def get_header_data(filename):
    try:
        with open(filename, "rb") as f:
            dialect, has_header = sniff_csv(f)
	    dialect.delimiter =','
            data = list(csv.reader(f, dialect))
            if has_header:
                data_header = data[0]
                data = data[1:]
                return True,data_header,data
            else:
                return False,None,data
    except:
        with open(filename,"rb") as f:
            data_header_len = 0
            data = []
            while 1:
                line = f.readline()
                if not line :
                    break
                data_header_len=len(line.split(','))
                data.append(line.rstrip('\n').split(','))
            return False,None,data

def main():
    settings = get_settings_from_file("spec.json")
    print(settings)

    # TODO: Add your code here

    left_part = get_header_data(settings.Input.x)
    right_part = get_header_data(settings.Input.y)

    file_merged = open(settings.Output.merged_file,"wb")
    writer = csv.writer(file_merged)

    if(left_part[0] and right_part[0] ):
        left_part[1].extend(right_part[1])
        writer.writerow(left_part[1])
    if(len(left_part[2]) != len(right_part[2])):
        raise Exception("The x.csv has a different line number from y.csv. Can not merge.")

    for i in range(len(left_part[2])):
        l = left_part[2][i]
        r = right_part[2][i]
        l.extend(r)
        writer.writerow(l)
    file_merged.close()

    print("Done")

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>"""
Allows setting a date range for when the page is active. Modifies the active()
manager method so that only pages inside the given range are used in the
default views and the template tags.

Depends on the page class having a "active_filters" list that will be used by
the page's manager to determine which entries are to be considered active.
"""
# ------------------------------------------------------------------------

from __future__ import absolute_import, unicode_literals

from datetime import datetime

from django.db import models
from django.db.models import Q
from django.utils import timezone
from django.utils.cache import patch_response_headers
from django.utils.translation import ugettext_lazy as _

from feincms import extensions

# ------------------------------------------------------------------------
def format_date(d, if_none=''):
    """
    Format a date in a nice human readable way: Omit the year if it's the
    current year. Also return a default value if no date is passed in.
    """

    if d is None:
        return if_none

    now = timezone.now()
    fmt = (d.year == now.year) and '%d.%m' or '%d.%m.%Y'
    return d.strftime(fmt)

def latest_children(self):
    return self.get_children().order_by('-publication_date')

# ------------------------------------------------------------------------
def granular_now(n=None):
    """
    A datetime.now look-alike that returns times rounded to a five minute
    boundary. This helps the backend database to optimize/reuse/cache its
    queries by not creating a brand new query each time.

    Also useful if you are using johnny-cache or a similar queryset cache.
    """
    if n is None:
        n = timezone.now()
    # WARNING/TODO: make_aware can raise a pytz NonExistentTimeError or
    # AmbiguousTimeError if the resultant time is invalid in n.tzinfo
    # -- see https://github.com/feincms/feincms/commit/5d0363df
    return timezone.make_aware(
        datetime(n.year, n.month, n.day, n.hour, (n.minute // 5) * 5),
        n.tzinfo)

# ------------------------------------------------------------------------
def datepublisher_response_processor(page, request, response):
    """
    This response processor is automatically added when the datepublisher
    extension is registered. It sets the response headers to match with
    the publication end date of the page so that upstream caches and
    the django caching middleware know when to expunge the copy.
    """
    expires = page.publication_end_date
    if expires is not None:
        delta = expires - timezone.now()
        delta = int(delta.days * 86400 + delta.seconds)
        patch_response_headers(response, delta)

# ------------------------------------------------------------------------
class Extension(extensions.Extension):
    def handle_model(self):
        self.model.add_to_class(
            'publication_date',
            models.DateTimeField(_('publication date'), default=granular_now))
        self.model.add_to_class(
            'publication_end_date',
            models.DateTimeField(
                _('publication end date'),
                blank=True, null=True,
                help_text=_(
                    'Leave empty if the entry should stay active forever.')))
        self.model.add_to_class('latest_children', latest_children)

        # Patch in rounding the pub and pub_end dates on save
        orig_save = self.model.save

        def granular_save(obj, *args, **kwargs):
            if obj.publication_date:
                obj.publication_date = granular_now(obj.publication_date)
            if obj.publication_end_date:
                obj.publication_end_date = granular_now(
                    obj.publication_end_date)
            orig_save(obj, *args, **kwargs)
        self.model.save = granular_save

        # Append publication date active check
        if hasattr(self.model._default_manager, 'add_to_active_filters'):
            self.model._default_manager.add_to_active_filters(
                Q(publication_date__lte=granular_now) &
                 (Q(publication_end_date__isnull=True) |
                  Q(publication_end_date__gt=granular_now)),
                key='datepublisher',
            )

        # Processor to patch up response headers for expiry date
        self.model.register_response_processor(
            datepublisher_response_processor)

    def handle_modeladmin(self, modeladmin):
        def datepublisher_admin(self, obj):
            return '%s – %s' % (
                format_date(obj.publication_date),
                format_date(obj.publication_end_date, '∞'),
            )
        datepublisher_admin.allow_tags = True
        datepublisher_admin.short_description = _('visible from - to')

        modeladmin.__class__.datepublisher_admin = datepublisher_admin

        try:
            pos = modeladmin.list_display.index('is_visible_admin')
        except ValueError:
            pos = len(modeladmin.list_display)

        modeladmin.list_display.insert(pos + 1, 'datepublisher_admin')

        modeladmin.add_extension_options(_('Date-based publishing'), {
            'fields': ['publication_date', 'publication_end_date'],
        })

# ------------------------------------------------------------------------
<commit_msg>Fix #408 for good<commit_after>"""
Allows setting a date range for when the page is active. Modifies the active()
manager method so that only pages inside the given range are used in the
default views and the template tags.

Depends on the page class having a "active_filters" list that will be used by
the page's manager to determine which entries are to be considered active.
"""
# ------------------------------------------------------------------------

from __future__ import absolute_import, unicode_literals

from datetime import datetime

from django.db import models
from django.db.models import Q
from django.utils import timezone
from django.utils.cache import patch_response_headers
from django.utils.translation import ugettext_lazy as _

from feincms import extensions

try:
    from pytz import InvalidTimeError
except ImportError:
    # Fall back to a catch-all
    InvalidTimeError = Exception

# ------------------------------------------------------------------------
def format_date(d, if_none=''):
    """
    Format a date in a nice human readable way: Omit the year if it's the
    current year. Also return a default value if no date is passed in.
    """

    if d is None:
        return if_none

    now = timezone.now()
    fmt = (d.year == now.year) and '%d.%m' or '%d.%m.%Y'
    return d.strftime(fmt)

def latest_children(self):
    return self.get_children().order_by('-publication_date')

# ------------------------------------------------------------------------
def granular_now(n=None):
    """
    A datetime.now look-alike that returns times rounded to a five minute
    boundary. This helps the backend database to optimize/reuse/cache its
    queries by not creating a brand new query each time.

    Also useful if you are using johnny-cache or a similar queryset cache.
    """
    if n is None:
        n = timezone.now()
    # WARNING/TODO: make_aware can raise a pytz NonExistentTimeError or
    # AmbiguousTimeError if the resultant time is invalid in n.tzinfo
    # -- see https://github.com/feincms/feincms/commit/5d0363df
    return timezone.make_aware(
        datetime(n.year, n.month, n.day, n.hour, (n.minute // 5) * 5),
        n.tzinfo)

# ------------------------------------------------------------------------
def datepublisher_response_processor(page, request, response):
    """
    This response processor is automatically added when the datepublisher
    extension is registered. It sets the response headers to match with
    the publication end date of the page so that upstream caches and
    the django caching middleware know when to expunge the copy.
    """
    expires = page.publication_end_date
    if expires is not None:
        delta = expires - timezone.now()
        delta = int(delta.days * 86400 + delta.seconds)
        try:
            patch_response_headers(response, delta)
        except InvalidTimeError:  # NonExistentTimeError and AmbiguousTimeError
            patch_response_headers(response, delta - 7200)

# ------------------------------------------------------------------------
class Extension(extensions.Extension):
    def handle_model(self):
        self.model.add_to_class(
            'publication_date',
            models.DateTimeField(_('publication date'), default=granular_now))
        self.model.add_to_class(
            'publication_end_date',
            models.DateTimeField(
                _('publication end date'),
                blank=True, null=True,
                help_text=_(
                    'Leave empty if the entry should stay active forever.')))
        self.model.add_to_class('latest_children', latest_children)

        # Patch in rounding the pub and pub_end dates on save
        orig_save = self.model.save

        def granular_save(obj, *args, **kwargs):
            if obj.publication_date:
                obj.publication_date = granular_now(obj.publication_date)
            if obj.publication_end_date:
                obj.publication_end_date = granular_now(
                    obj.publication_end_date)
            orig_save(obj, *args, **kwargs)
        self.model.save = granular_save

        # Append publication date active check
        if hasattr(self.model._default_manager, 'add_to_active_filters'):
            self.model._default_manager.add_to_active_filters(
                Q(publication_date__lte=granular_now) &
                 (Q(publication_end_date__isnull=True) |
                  Q(publication_end_date__gt=granular_now)),
                key='datepublisher',
            )

        # Processor to patch up response headers for expiry date
        self.model.register_response_processor(
            datepublisher_response_processor)

    def handle_modeladmin(self, modeladmin):
        def datepublisher_admin(self, obj):
            return '%s – %s' % (
                format_date(obj.publication_date),
                format_date(obj.publication_end_date, '∞'),
            )
        datepublisher_admin.allow_tags = True
        datepublisher_admin.short_description = _('visible from - to')

        modeladmin.__class__.datepublisher_admin = datepublisher_admin

        try:
            pos = modeladmin.list_display.index('is_visible_admin')
        except ValueError:
            pos = len(modeladmin.list_display)

        modeladmin.list_display.insert(pos + 1, 'datepublisher_admin')

        modeladmin.add_extension_options(_('Date-based publishing'), {
            'fields': ['publication_date', 'publication_end_date'],
        })

# ------------------------------------------------------------------------
<|endoftext|>


<commit_before>from org.eclipse.scanning.api.points import Point
from org.eclipse.scanning.api.points import Scalar
from org.eclipse.scanning.api.points import MapPosition
from org.eclipse.scanning.points import SerializableIterator
from java.util import ArrayList

from scanpointgenerator import LineGenerator
from scanpointgenerator import ArrayGenerator
from scanpointgenerator import SpiralGenerator
from scanpointgenerator import LissajousGenerator
from scanpointgenerator import CompoundGenerator
from scanpointgenerator import RandomOffsetMutator

# logging
import logging
# logging.basicConfig(level=logging.DEBUG)

class JavaIteratorWrapper(SerializableIterator):
    """
    A wrapper class to give a python iterator the while(hasNext() {next()})
    operation required of Java Iterators
    """

    def __init__(self):
        self._iterator = iter(self._iterator())
        self._has_next = None
        self._next = None

    def iterator(self):
        return self

    def _iterator(self):
        raise NotImplementedError("Must be implemented in child class")

    def next(self):

        if self._has_next:
            result = self._next
        else:
            result = self._iterator.next()  # Note: No next() in Py3

        self._has_next = None

        return result

    def hasNext(self):

        if self._has_next is None:

            try:
                self._next = self._iterator.next()  # Note: No next() in Py3
            except StopIteration:
                self._has_next = False
            else:
                self._has_next = True

        return self._has_next

    def toDict(self):
        return self.generator.to_dict()

    def size(self):
        return self.generator.num

class JLineGenerator1D(JavaIteratorWrapper):
    """
    Create a 1D LineGenerator and wrap the points into java Scalar objects
    """

    def __init__(self, name, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator1D, self).__init__()

        self.name = name
        self.generator = LineGenerator(name, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            index = point.indexes[0]
            position = point.positions[self.name]
            java_point = Scalar(self.name, index, position)

            yield java_point

class JLineGenerator2D(JavaIteratorWrapper):
    """
    Create a 2D LineGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator2D, self).__init__()

        start = start.tolist()  # Convert from array to list
        stop = stop.tolist()

        self.names = names
        self.generator = LineGenerator(names, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            index = point.indexes[0]
            xName = self.names[0]
            yName = self.names[1]
            xPosition = point.positions[xName]
            yPosition = point.positions[yName]
            java_point = Point(xName, index, xPosition,
                               yName, index, yPosition, False)
            # Set is2D=False

            yield java_point

class JArrayGenerator(JavaIteratorWrapper):
    """
    Create an ArrayGenerator and wrap the points into java Scalar objects
    """

    def __init__(self, name, units, points):
        super(JArrayGenerator, self).__init__()

        points = points.tolist()  # Convert from array to list

        self.name = name
        self.generator = ArrayGenerator(name, units, points)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            name = self.name[0]
            index = point.indexes[0]
            position = point.positions[name]
            java_point = Scalar(name, index, position)

            yield java_point

class JSpiralGenerator(JavaIteratorWrapper):
    """
    Create a SpiralGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, centre, radius, scale=1.0, alternate_direction=False):
        super(JSpiralGenerator, self).__init__()

        self.names = names
        self.generator = SpiralGenerator(names, units, centre, radius, scale, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        xName = self.names[0]
        yName = self.names[1]

        for point in self.generator.iterator():
            index = point.indexes[0]
            xPosition = point.positions[xName]
            yPosition = point.positions[yName]
            java_point = Point(xName, index, xPosition,
                               yName, index, yPosition, False)
            # Set is2D=False

            yield java_point

class JLissajousGenerator(JavaIteratorWrapper):
    """
    Create a LissajousGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, box, num_lobes, num_points):
        super(JLissajousGenerator, self).__init__()

        self.names = names
        self.generator = LissajousGenerator(names, units, box, num_lobes, num_points)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        xName = self.names[0]
        yName = self.names[1]

        for point in self.generator.iterator():
            index = point.indexes[0]
            xPosition = point.positions[xName]
            yPosition = point.positions[yName]
            java_point = Point(xName, index, xPosition,
                               yName, index, yPosition, False)
            # Set is2D=False

            yield java_point

class JCompoundGenerator(JavaIteratorWrapper):
    """
    Create a CompoundGenerator and wrap the points into java Point objects
    """

    def __init__(self, iterators, excluders, mutators):
        super(JCompoundGenerator, self).__init__()

        try: # If JavaIteratorWrapper
            generators = [iterator.generator for iterator in iterators]
        except AttributeError: # Else call get*() of Java iterator
            generators = [iterator.getPyIterator().generator for iterator in iterators]
        logging.debug("Generators passed to JCompoundGenerator:")
        logging.debug([generator.to_dict() for generator in generators])

        excluders = [excluder.py_excluder for excluder in excluders]
        mutators = [mutator.py_mutator for mutator in mutators]

        extracted_generators = []
        for generator in generators:
            if generator.__class__.__name__ == "CompoundGenerator":
                extracted_generators.extend(generator.generators)
            else:
                extracted_generators.append(generator)
        generators = extracted_generators

        self.index_locations = {}
        self.dimension_names = ArrayList()
        self.axes_ordering = []
        for index, generator in enumerate(generators):

            for axis in generator.axes:
                self.index_locations[axis] = index
                self.axes_ordering.append(axis)

                scan_name = ArrayList()
                for axis in generator.axes:
                    scan_name.add(axis)

            self.dimension_names.add(scan_name)

        logging.debug("Index Locations:")
        logging.debug(self.index_locations)

        self.generator = CompoundGenerator(generators, excluders, mutators)

        logging.debug("CompoundGenerator:")
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():

            if len(point.positions.keys()) == 1:
                name = point.positions.keys()[0]
                index = point.indexes[0]
                position = point.positions[name]
                java_point = Scalar(name, index, position)

            elif len(point.positions.keys()) == 2:
                xName = self.generator.axes[1]
                yName = self.generator.axes[0]
                xIndex = point.indexes[1]
                yIndex = point.indexes[0]
                xPosition = point.positions[xName]
                yPosition = point.positions[yName]
                java_point = Point(xName, xIndex, xPosition,
                                   yName, yIndex, yPosition)
            else:
                java_point = MapPosition()

                for axis in self.axes_ordering:
                    index = self.index_locations[axis]
                    logging.debug([index, point.indexes, point.positions])
                    value = point.positions[axis]
                    java_point.put(axis, value)
                    java_point.putIndex(axis, point.indexes[index])

                java_point.setDimensionNames(self.dimension_names)

            yield java_point

class JRandomOffsetMutator(object):

    def __init__(self, seed, axes, max_offset):
        self.py_mutator = RandomOffsetMutator(seed, axes, max_offset)
        logging.debug(self.py_mutator.to_dict())
<commit_msg>Tidy and add comments to spg interface<commit_after>from org.eclipse.scanning.api.points import Point
from org.eclipse.scanning.api.points import Scalar
from org.eclipse.scanning.api.points import MapPosition
from org.eclipse.scanning.points import SerializableIterator
from java.util import ArrayList

from scanpointgenerator import LineGenerator
from scanpointgenerator import ArrayGenerator
from scanpointgenerator import SpiralGenerator
from scanpointgenerator import LissajousGenerator
from scanpointgenerator import CompoundGenerator
from scanpointgenerator import RandomOffsetMutator

## Logging
import logging
# logging.basicConfig(level=logging.DEBUG)

class JavaIteratorWrapper(SerializableIterator):
    """
    A wrapper class to give a python iterator the while(hasNext()) next()
    operation required of Java Iterators
    """

    def __init__(self):
        self._iterator = self._iterator()  # Store single instance of _iterator()
        self._has_next = None
        self._next = None

    def _iterator(self):
        raise NotImplementedError("Must be implemented in child class")

    def next(self):

        if self._has_next:
            result = self._next
        else:
            result = self._iterator.next()  # Note: No next() in Py3

        self._has_next = None

        return result

    def hasNext(self):

        if self._has_next is None:

            try:
                self._next = self._iterator.next()  # Note: No next() in Py3
            except StopIteration:
                self._has_next = False
            else:
                self._has_next = True

        return self._has_next

    def toDict(self):
        return self.generator.to_dict()

    def size(self):
        return self.generator.num

class JLineGenerator1D(JavaIteratorWrapper):
    """
    Create a 1D LineGenerator and wrap the points into java Scalar objects
    """

    def __init__(self, name, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator1D, self).__init__()

        self.name = name
        self.generator = LineGenerator(name, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            index = point.indexes[0]
            position = point.positions[self.name]
            java_point = Scalar(self.name, index, position)

            yield java_point

class JLineGenerator2D(JavaIteratorWrapper):
    """
    Create a 2D LineGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator2D, self).__init__()

        start = start.tolist()  # Convert from array to list
        stop = stop.tolist()

        self.names = names
        self.generator = LineGenerator(names, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            index = point.indexes[0]
            x_name = self.names[0]
            y_name = self.names[1]
            x_position = point.positions[x_name]
            y_position = point.positions[y_name]
            java_point = Point(x_name, index, x_position,
                               y_name, index, y_position, False)
            # Set is2D=False

            yield java_point

class JArrayGenerator(JavaIteratorWrapper):
    """
    Create an ArrayGenerator and wrap the points into java Scalar objects
    """

    def __init__(self, name, units, points):
        super(JArrayGenerator, self).__init__()

        points = points.tolist()  # Convert from array to list

        self.name = name
        self.generator = ArrayGenerator(name, units, points)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():
            name = self.name[0]
            index = point.indexes[0]
            position = point.positions[name]
            java_point = Scalar(name, index, position)

            yield java_point

class JSpiralGenerator(JavaIteratorWrapper):
    """
    Create a SpiralGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, centre, radius, scale=1.0, alternate_direction=False):
        super(JSpiralGenerator, self).__init__()

        self.names = names
        self.generator = SpiralGenerator(names, units, centre, radius, scale, alternate_direction)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        x_name = self.names[0]
        y_name = self.names[1]

        for point in self.generator.iterator():
            index = point.indexes[0]
            x_position = point.positions[x_name]
            y_position = point.positions[y_name]
            java_point = Point(x_name, index, x_position,
                               y_name, index, y_position, False)
            # Set is2D=False

            yield java_point

class JLissajousGenerator(JavaIteratorWrapper):
    """
    Create a LissajousGenerator and wrap the points into java Point objects
    """

    def __init__(self, names, units, box, num_lobes, num_points):
        super(JLissajousGenerator, self).__init__()

        self.names = names
        self.generator = LissajousGenerator(names, units, box, num_lobes, num_points)
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        x_name = self.names[0]
        y_name = self.names[1]

        for point in self.generator.iterator():
            index = point.indexes[0]
            x_position = point.positions[x_name]
            y_position = point.positions[y_name]
            java_point = Point(x_name, index, x_position,
                               y_name, index, y_position, False)
            # Set is2D=False

            yield java_point

class JCompoundGenerator(JavaIteratorWrapper):
    """
    Create a CompoundGenerator and wrap the points into java Point objects
    """

    def __init__(self, iterators, excluders, mutators):
        super(JCompoundGenerator, self).__init__()

        try:  # If JavaIteratorWrapper
            generators = [iterator.generator for iterator in iterators]
        except AttributeError:  # Else call get*() of Java iterator
            generators = [iterator.getPyIterator().generator for iterator in iterators]
        logging.debug("Generators passed to JCompoundGenerator:")
        logging.debug([generator.to_dict() for generator in generators])

        excluders = [excluder.py_excluder for excluder in excluders]
        mutators = [mutator.py_mutator for mutator in mutators]

        extracted_generators = []
        for generator in generators:
            if generator.__class__.__name__ == "CompoundGenerator":
                extracted_generators.extend(generator.generators)
            else:
                extracted_generators.append(generator)
        generators = extracted_generators

        self.index_locations = {}
        self.dimension_names = ArrayList()
        self.axes_ordering = []
        for index, generator in enumerate(generators):

            scan_name = ArrayList()
            for axis in generator.axes:
                self.index_locations[axis] = index
                self.axes_ordering.append(axis)
                scan_name.add(axis)

            self.dimension_names.add(scan_name)

        logging.debug("Index Locations:")
        logging.debug(self.index_locations)

        self.generator = CompoundGenerator(generators, excluders, mutators)

        logging.debug("CompoundGenerator:")
        logging.debug(self.generator.to_dict())

    def _iterator(self):

        for point in self.generator.iterator():

            if len(point.positions.keys()) == 1:
                name = point.positions.keys()[0]
                index = point.indexes[0]
                position = point.positions[name]
                java_point = Scalar(name, index, position)

            elif len(point.positions.keys()) == 2:
                x_name = self.generator.axes[1]
                y_name = self.generator.axes[0]
                x_index = point.indexes[1]
                y_index = point.indexes[0]
                x_position = point.positions[x_name]
                y_position = point.positions[y_name]
                java_point = Point(x_name, x_index, x_position,
                                   y_name, y_index, y_position)
            else:
                java_point = MapPosition()

                for axis in self.axes_ordering:
                    index = self.index_locations[axis]
                    logging.debug([index, point.indexes, point.positions])
                    value = point.positions[axis]
                    java_point.put(axis, value)
                    java_point.putIndex(axis, point.indexes[index])

                java_point.setDimensionNames(self.dimension_names)

            yield java_point

class JRandomOffsetMutator(object):

    def __init__(self, seed, axes, max_offset):
        self.py_mutator = RandomOffsetMutator(seed, axes, max_offset)
        logging.debug(self.py_mutator.to_dict())
<|endoftext|>