コード例 #1
0
ファイル: test_containers.py プロジェクト: mbr/flatland0
def test_no_duplicates_list_anon_dict():
    nd = NotDuplicated(failure=u'%(container_label)s %(position)s')
    schema = (List.named('test').
              of(Dict.of(Integer.named('x'),
                         Integer.named('y')).
                 using(validators=[nd])))
    _test_no_duplicates(schema, {'x': 1, 'y': 2}, {'x': 3, 'y': 4})
コード例 #2
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_set_default():
    schema = SparseDict.of(Integer.named(u'x').using(default=123),
                           Integer.named(u'y'))
    el = schema()

    el.set_default()
    assert el.value == {}
コード例 #3
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_dict_el():
    # stub
    schema = Dict.named(u's').of(Integer.named(u'x'), Integer.named(u'y'))
    element = schema()

    assert element.el(u'x').name == u'x'
    assert_raises(KeyError, element.el, u'not_x')
コード例 #4
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_access():
    pairs = ((u'l_0_i', u'10'), (u'l_1_i', u'11'), (u'l_2_i', u'12'),)

    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema.from_flat(pairs)

    elements = list(Integer.named(u'i')(val)
                    for val in (u'10', u'11', u'12'))

    assert len(el) == 3
    assert el[0] == elements[0]
    assert el[1] == elements[1]
    assert el[2] == elements[2]

    assert el[0].value == 10

    assert el[:0] == elements[:0]
    assert el[:1] == elements[:1]
    assert el[0:5] == elements[0:5]
    assert el[-2:-1] == elements[-2:-1]

    assert el[0] in el
    assert elements[0] in el
    assert u'10' in el
    assert 10 in el

    assert el.count(elements[0]) == 1
    assert el.count(u'10') == 1
    assert el.count(10) == 1

    assert el.index(elements[0]) == 0
    assert el.index(u'10') == 0
    assert el.index(10) == 0
コード例 #5
0
ファイル: test_containers.py プロジェクト: dag/flatland
def test_dsl_of():
    assert_raises(TypeError, Sequence.of)

    t1 = Sequence.of(Integer)
    assert t1.member_schema is Integer

    t2 = Sequence.of(Integer.named(u'x'), Integer.named(u'y'))
    assert issubclass(t2.member_schema, Dict)
    assert sorted(t2.member_schema().keys()) == [u'x', u'y']
コード例 #6
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_required_set_default():
    schema = SparseDict.using(minimum_fields='required').\
                        of(Integer.named(u'x').using(default=123),
                           Integer.named(u'y').using(default=456,
                                                     optional=True),
                           Integer.named(u'z').using(optional=True))
    el = schema()

    el.set_default()
    assert el.value == {u'x': 123}
コード例 #7
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_dict_strict():
    # a mini test, this policy thing may get whacked
    schema = Dict.using(policy='strict').of(Integer.named(u'x'),
                                            Integer.named(u'y'))

    el = schema({u'x': 123, u'y': 456})

    el = schema()
    assert_raises(TypeError, el.set, {u'x': 123})

    el = schema()
    assert_raises(KeyError, el.set, {u'x': 123, u'y': 456, u'z': 7})
コード例 #8
0
ファイル: test_dicts.py プロジェクト: dag/flatland
    def new_schema(self):
        dictkw, x_kw, y_kw = {}, {}, {}
        if self.policy is not Unspecified:
            dictkw['policy'] = self.policy
        if self.x_default is not Unspecified:
            x_kw['default'] = self.x_default
        if self.y_default is not Unspecified:
            y_kw['default'] = self.y_default

        return self.schema.named(u's').using(**dictkw).of(
            Integer.named(u'x').using(**x_kw),
            Integer.named(u'y').using(**y_kw))
コード例 #9
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_from_flat():
    schema = SparseDict.of(Integer.named(u'x'),
                           Integer.named(u'y'))

    el = schema.from_flat([])
    assert el.items() == []

    el = schema.from_flat([(u'x', u'123')])
    assert el.value == {u'x': 123}

    el = schema.from_flat([(u'x', u'123'), (u'z', u'456')])
    assert el.value == {u'x': 123}
コード例 #10
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_mutation():
    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema()

    new_element = Integer.named(u'i')

    def order_ok():
        slot_names = list(_.name for _ in el._slots)
        for idx, name in enumerate(slot_names):
            assert name == str(idx).decode('ascii')

    assert not el
    order_ok()

    # FIXME:? seems to want parsable data, not elements
    el.append(new_element(u'0'))
    assert el.value == [0]
    order_ok()

    el.append(u'123')
    assert el.value == [0, 123]
    order_ok()

    el.extend([u'4', u'5'])
    assert el.value == [0, 123, 4, 5]
    order_ok()

    el[0] = u'3'
    assert el.value == [3, 123, 4, 5]
    order_ok()

    el.insert(0, u'2')
    assert el.value == [2, 3, 123, 4, 5]
    order_ok()

    v = el.pop()
    assert v.value == 5
    assert not v.parent
    order_ok()

    v = el.pop(0)
    assert v.value == 2
    assert el.value == [3, 123, 4]
    order_ok()

    el.remove(u'3')
    assert el.value == [123, 4]
    order_ok()

    del el[:]
    assert el.value == []
    order_ok()
コード例 #11
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_required_from_flat():
    schema = SparseDict.of(Integer.named(u'x'),
                           Integer.named(u'y').using(optional=True)).\
                        using(minimum_fields='required')

    el = schema.from_flat([])
    assert el.value == {u'x': None}

    el = schema.from_flat([(u'x', u'123')])
    assert el.value == {u'x': 123}

    el = schema.from_flat([(u'y', u'456'), (u'z', u'789')])
    assert el.value == {u'x': None, u'y': 456}
コード例 #12
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_required_validation():
    schema = SparseDict.of(Integer.named(u'x'),
                           Integer.named(u'y').using(optional=True)).\
                        using(minimum_fields='required')

    el = schema()
    assert not el.validate()

    el = schema({u'y': 456})
    assert not el.validate()

    el = schema({u'x': 123, u'y': 456})
    assert el.validate()
コード例 #13
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_dict_immutable_keys():
    schema = Dict.of(Integer.named(u'x'), Integer.named(u'y'))
    el = schema()

    assert_raises(TypeError, el.__setitem__, u'z', 123)
    assert_raises(TypeError, el.__delitem__, u'x')
    assert_raises(KeyError, el.__delitem__, u'z')
    assert_raises(TypeError, el.setdefault, u'x', 123)
    assert_raises(TypeError, el.setdefault, u'z', 123)
    assert_raises(TypeError, el.pop, u'x')
    assert_raises(KeyError, el.pop, u'z')
    assert_raises(TypeError, el.popitem)
    assert_raises(TypeError, el.clear)
コード例 #14
0
ファイル: test_containers.py プロジェクト: dag/flatland
def test_simple_validation_shortcircuit():
    Regular = Dict.of(Integer.using(optional=False))
    el = Regular()
    assert not el.validate()

    def boom(element, state):
        assert False
    all_ok = lambda element, state: SkipAll

    Boom = Integer.named(u'i').using(validators=[boom])

    ShortCircuited = Dict.of(Boom).using(descent_validators=[all_ok])
    el = ShortCircuited()
    assert el.validate()
コード例 #15
0
ファイル: test_scalars.py プロジェクト: mbr/flatland0
def test_scalar_set_default():
    el = Integer()
    el.set_default()
    assert el.value is None

    el = Integer(default=10)
    el.set_default()
    assert el.value == 10

    el = Integer(default_factory=lambda e: 20)
    el.set_default()
    assert el.value == 20
コード例 #16
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_nested_dict_as_unicode():
    schema = Dict.of(Dict.named(u'd').of(
        Integer.named(u'x').using(default=10)))
    el = schema.from_defaults()

    eq_(el.value, {u'd': {u'x': 10}})
    eq_(el.u, u"{u'd': {u'x': u'10'}}")
コード例 #17
0
    def _populate_app_fields(self):
        with WindowServiceProxy(59000) as w:
            self.video_mode_map = w.get_video_mode_map()
            if self.video_mode_map:
                self._video_available = True
            else:
                self._video_available = False
            self.video_mode_keys = sorted(self.video_mode_map.keys())
            if self._video_available:
                self.device_key, self.devices = w.get_video_source_configs()

        field_list = [
            Integer.named('overlay_opacity').using(default=50, optional=True),
            Directory.named('device_directory').using(default='', optional=True),
            String.named('transform_matrix').using(default='', optional=True,
                                                properties={'show_in_gui':
                                                            False}), ]

        if self._video_available:
            video_mode_enum = Enum.named('video_mode').valued(
                *self.video_mode_keys).using(default=self.video_mode_keys[0],
                                             optional=True)
            video_enabled_boolean = Boolean.named('video_enabled').using(
                default=False, optional=True, properties={'show_in_gui': True})
            recording_enabled_boolean = Boolean.named('recording_enabled').using(
                default=False, optional=True, properties={'show_in_gui': False})
            field_list.append(video_mode_enum)
            field_list.append(video_enabled_boolean)
            field_list.append(recording_enabled_boolean)
        return Form.of(*field_list)
コード例 #18
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_reverse():
    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema([2, 1])
    assert el.flatten() == [(u'l_0_i', u'2'), (u'l_1_i', u'1')]

    el.reverse()
    assert el.value == [1, 2]
    assert el.flatten() == [(u'l_0_i', u'1'), (u'l_1_i', u'2')]
コード例 #19
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_set_flat_miss():
    pairs = [(u'l_galump', u'3'), (u'l_snorgle', u'4')]

    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema.from_flat(pairs)

    eq_(len(el), 0)
    eq_(el.value, [])
コード例 #20
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_set_flat_linear():
    pairs = [(u'l_0_i', 1), (u'l_1_i', 2), (u'l_2_i', 3)]

    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema.from_flat(pairs)

    eq_(len(el), len(pairs))
    eq_(el.value, list(pair[1] for pair in pairs))
コード例 #21
0
ファイル: test_refs.py プロジェクト: mbr/flatland0
def test_not_writable():
    schema = Dict.of(Integer.named(u'main'),
                     Ref.named(u'aux').to(u'main').using(writable=False))

    el = schema()

    with pytest.raises(TypeError):
        el[u'aux'].set(6)
コード例 #22
0
ファイル: test_refs.py プロジェクト: mbr/flatland0
def test_writable():
    schema = Dict.of(Integer.named(u'main'),
                     Ref.named(u'aux').to(u'main').using(writable=True))

    el = schema()
    el[u'aux'] = 6
    assert el[u'main'].value == 6
    assert el[u'aux'].value == 6
コード例 #23
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_slots():
    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema([1, 2])

    assert len(list(el._slots)) == 2
    for slot in el._slots:
        # don't really care what it says, just no crashy.
        assert repr(slot)

    assert [slot.value for slot in el._slots] == [1, 2]
コード例 #24
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_operations():
    schema = SparseDict.of(Integer.named(u'x'), Integer.named(u'y'))
    el = schema()

    el[u'x'] = 123
    del el[u'x']
    assert_raises(KeyError, el.__delitem__, u'x')

    assert el.setdefault(u'x', 123) == 123
    assert el.setdefault(u'x', 456) == 123

    assert el.setdefault(u'y', 123) == 123
    assert el.setdefault(u'y', 456) == 123

    assert schema().is_empty
    assert not schema().validate()

    opt_schema = schema.using(optional=True)
    assert opt_schema().validate()
コード例 #25
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_dict_update():
    schema = Dict.of(Integer.named(u'x'), Integer.named(u'y'))
    el = schema()

    def value_dict(element):
        return dict((k, v.value) for k, v in element.iteritems())

    try:
        el.update(x=20, y=30)
    except UnicodeError:
        assert not unicode_coercion_available()
        el.update(udict(x=20, y=30))
    assert udict(x=20, y=30) == el.value

    el.update({u'y': 40})
    assert udict(x=20, y=40) == el.value

    el.update()
    assert udict(x=20, y=40) == el.value

    el.update((_, 100) for _ in u'xy')
    assert udict(x=100, y=100) == el.value

    try:
        el.update([(u'x', 1)], y=2)
        assert udict(x=1, y=2) == el.value
    except UnicodeError:
        assert not unicode_coercion_available()

    try:
        el.update([(u'x', 10), (u'y', 10)], x=20, y=20)
        assert udict(x=20, y=20) == el.value
    except UnicodeError:
        assert not unicode_coercion_available()

    if unicode_coercion_available():
        assert_raises(TypeError, el.update, z=1)
        assert_raises(TypeError, el.update, x=1, z=1)
    assert_raises(TypeError, el.update, {u'z': 1})
    assert_raises(TypeError, el.update, {u'x': 1, u'z': 1})
    assert_raises(TypeError, el.update, ((u'z', 1),))
    assert_raises(TypeError, el.update, ((u'x', 1), (u'z', 1)))
コード例 #26
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_required_operations():
    schema = SparseDict.using(minimum_fields='required').\
                        of(Integer.named(u'opt').using(optional=True),
                           Integer.named(u'req'))

    el = schema({u'opt': 123, u'req': 456})

    del el[u'opt']
    assert_raises(KeyError, el.__delitem__, u'opt')
    assert_raises(TypeError, el.__delitem__, u'req')

    el = schema()
    assert el.setdefault(u'opt', 123) == 123
    assert el.setdefault(u'opt', 456) == 123

    assert el.setdefault(u'req', 123) == 123
    assert el.setdefault(u'req', 456) == 123

    assert not schema().is_empty
    assert not schema().validate()
コード例 #27
0
ファイル: test_dicts.py プロジェクト: dag/flatland
def test_sparsedict_flattening():
    schema = SparseDict.named(u'top').\
                        of(Integer.named(u'x'), Integer.named(u'y'))

    els = [
        schema({'x': 123, 'y': 456}),
        schema(),
        schema(),
        schema(),
        ]
    els[1].set({'x': 123, 'y': 456})
    els[2]['x'] = 123
    els[2]['y'] = 456
    els[3]['x'] = Integer(123)
    els[3]['y'] = Integer(456)

    wanted = [(u'top_x', u'123'), (u'top_y', u'456')]
    for el in els:
        got = sorted(el.flatten())
        assert wanted == got
コード例 #28
0
ファイル: test_lists.py プロジェクト: dag/flatland
def test_sort():
    schema = List.named(u'l').of(Integer.named(u'i'))
    el = schema([2, 1])

    el.sort(key=lambda el: el.value)
    assert el.value == [1, 2]
    assert el.flatten() == [(u'l_0_i', u'1'), (u'l_1_i', u'2')]

    el.sort(key=lambda el: el.value, reverse=True)
    assert el.value == [2, 1]
    assert el.flatten() == [(u'l_0_i', u'2'), (u'l_1_i', u'1')]
コード例 #29
0
ファイル: test_containers.py プロジェクト: dag/flatland
 def test_shortcircuit_up(self):
     schema = (
         Dict.of(
             Integer.using(validators=[self.validator('2', True)])).
         using(
             descent_validators=[self.validator('1', True)],
             validators=[self.validator('3', SkipAll)]))
     el = schema()
     assert el.validate()
     eq_(self.canary, ['1', '2', '3'])
     assert el.valid
     assert el.all_valid
コード例 #30
0
ファイル: test_containers.py プロジェクト: dag/flatland
 def test_paired3(self):
     schema = (
         Dict.of(
             Integer.using(validators=[self.validator('2', True)])).
         using(
             descent_validators=[self.validator('1', True)],
             validators=[self.validator('3', True)]))
     el = schema()
     assert el.validate()
     eq_(self.canary, ['1', '2', '3'])
     assert el.valid
     assert el.all_valid
コード例 #31
0
    class BA4(B, A):
        field_schema = [Integer.named('ab_member')]

        ab_member = String
コード例 #32
0
 def element(writable):
     ref = Ref.named(u'aux').to(u'main')
     if writable:
         ref = ref.using(writable=writable)
     return Dict.of(Integer.named(u'main'), ref)()
コード例 #33
0
def test_not_writable():
    schema = Dict.of(Integer.named(u'main'),
                     Ref.named(u'aux').to(u'main').using(writable=False))

    el = schema()
    assert_raises(TypeError, el[u'aux'].set, 6)
コード例 #34
0
        except re.error:
            valid = False
    if not valid:
        element.add_error("Subscription has invalid value.")
    return valid


common_meta = (
    String.named(keys.ITEMID).validated_by(itemid_validator),
    String.named(keys.REVID).validated_by(revid_validator),
    String.named(keys.PARENTID).validated_by(uuid_validator).using(optional=True),
    String.named(keys.WIKINAME).using(strip=False).validated_by(wikiname_validator),
    String.named(keys.NAMESPACE).using(strip=False).validated_by(namespace_validator),
    List.named(keys.NAME).of(String.using(strip=False).validated_by(name_validator)).using(optional=True),
    List.named(keys.NAME_OLD).of(String.using(strip=False).validated_by(name_validator)).using(optional=True),
    Integer.named(keys.MTIME).validated_by(mtime_validator),
    String.named(keys.ACTION).validated_by(action_validator),
    String.named(keys.ACL).validated_by(acl_validator),
    String.named(keys.COMMENT).validated_by(comment_validator),
    String.named(keys.ADDRESS).validated_by(address_validator),
    String.named(keys.HOSTNAME).validated_by(hostname_validator).using(optional=True),
    List.named(keys.TAGS).of(String.named('tag').validated_by(tag_validator)).using(optional=True),
)

ContentMetaSchema = DuckDict.named('ContentMetaSchema').of(
    String.named(keys.CONTENTTYPE).validated_by(contenttype_validator),
    String.named(keys.USERID).validated_by(userid_validator),
    Integer.named(keys.SIZE).validated_by(size_validator),
    String.named(keys.HASH_ALGORITHM).validated_by(hash_validator),
    String.named(keys.DATAID).validated_by(uuid_validator).using(optional=True),
    # markup items may have this:
コード例 #35
0
class DropletPlanningPlugin(Plugin, StepOptionsController, pmh.BaseMqttReactor):
    """
    This class is automatically registered with the PluginManager.
    """
    implements(IPlugin)
    version = get_plugin_info(path(__file__).parent).version
    plugin_name = get_plugin_info(path(__file__).parent).plugin_name

    '''
    StepFields
    ---------

    A flatland Form specifying the per step options for the current plugin.
    Note that nested Form objects are not supported.

    Since we subclassed StepOptionsController, an API is available to access and
    modify these attributes.  This API also provides some nice features
    automatically:
        -all fields listed here will be included in the protocol grid view
            (unless properties=dict(show_in_gui=False) is used)
        -the values of these fields will be stored persistently for each step
    '''
    StepFields = Form.of(
        Integer.named('trail_length').using(default=1, optional=True,
                                            validators=
                                            [ValueAtLeast(minimum=1)]),
        Integer.named('route_repeats').using(default=1, optional=True,
                                            validators=
                                            [ValueAtLeast(minimum=1)]),
        Integer.named('repeat_duration_s').using(default=0, optional=True),
        Integer.named('transition_duration_ms')
        .using(optional=True, default=750,
               validators=[ValueAtLeast(minimum=0)]))

    def __init__(self,*args, **kwargs):
        self.name = self.plugin_name
        self.step_start_time = None
        self.route_controller = None
        pmh.BaseMqttReactor.__init__(self)
        self.start()

    def get_schedule_requests(self, function_name):
        """
        Returns a list of scheduling requests (i.e., ScheduleRequest instances)
        for the function specified by function_name.
        """
        if function_name in ['on_step_run']:
            # Execute `on_step_run` before control board.
            return [ScheduleRequest(self.name, 'dmf_control_board_plugin')]
        return []

    def on_connect(self, client, userdata, flags, rc):
        self.mqtt_client.subscribe("microdrop/dmf-device-ui/add-route")
        self.mqtt_client.subscribe("microdrop/dmf-device-ui/get-routes")
        self.mqtt_client.subscribe("microdrop/dmf-device-ui/clear-routes")
        self.mqtt_client.subscribe('microdrop/dmf-device-ui/execute-routes')
        self.mqtt_client.subscribe('microdrop/dmf-device-ui/update-protocol')
        self.mqtt_client.subscribe("microdrop/mqtt-plugin/step-inserted")

    def on_message(self, client, userdata, msg):
        '''
        Callback for when a ``PUBLISH`` message is received from the broker.
        '''
        logger.info('[on_message] %s: "%s"', msg.topic, msg.payload)
        if msg.topic == 'microdrop/dmf-device-ui/add-route':
            self.add_route(json.loads(msg.payload))
            self.get_routes()
        if msg.topic == 'microdrop/dmf-device-ui/get-routes':
            self.get_routes()
        if msg.topic == 'microdrop/dmf-device-ui/clear-routes':
            data = json.loads(msg.payload)
            if data:
                self.clear_routes(electrode_id=data['electrode_id'])
            else:
                self.clear_routes()
        if msg.topic == 'microdrop/dmf-device-ui/execute-routes':
            self.execute_routes(json.loads(msg.payload))
        if msg.topic == 'microdrop/dmf-device-ui/update-protocol':
            self.update_protocol(json.loads(msg.payload))
        if msg.topic == "microdrop/mqtt-plugin/step-inserted":
            self.step_inserted(json.loads(msg.payload))

    def on_plugin_enable(self):
        self.route_controller = RouteController(self)
        form = flatlandToDict(self.StepFields)
        self.mqtt_client.publish('microdrop/droplet-planning-plugin/schema',
                                  json.dumps(form),
                                  retain=True)

        defaults = {}
        for k,v in form.iteritems():
            defaults[k] = v['default']
        self.mqtt_client.publish('microdrop/droplet-planning-plugin/step-options',
                                  json.dumps([defaults], cls=PandasJsonEncoder),
                                  retain=True)

    def on_plugin_disable(self):
        """
        Handler called once the plugin instance is disabled.
        """
        pass

    def on_app_exit(self):
        """
        Handler called just before the Microdrop application exits.
        """
        pass

    ###########################################################################
    # Step event handler methods
    def on_error(self, *args):
        logger.error('Error executing routes.', exc_info=True)
        # An error occurred while initializing Analyst remote control.
        emit_signal('on_step_complete', [self.name, 'Fail'])

    def on_protocol_pause(self):
        self.kill_running_step()

    def kill_running_step(self):
        # Stop execution of any routes that are currently running.
        if self.route_controller is not None:
            self.route_controller.reset()

    def on_step_run(self):
        """
        Handler called whenever a step is executed. Note that this signal
        is only emitted in realtime mode or if a protocol is running.

        Plugins that handle this signal must emit the on_step_complete
        signal once they have completed the step. The protocol controller
        will wait until all plugins have completed the current step before
        proceeding.

        return_value can be one of:
            None
            'Repeat' - repeat the step
            or 'Fail' - unrecoverable error (stop the protocol)
        """
        app = get_app()
        if not app.running:
            return

        self.kill_running_step()
        step_options = self.get_step_options()

        try:
            self.repeat_i = 0
            self.step_start_time = datetime.now()
            df_routes = self.get_routes()
            self.route_controller.execute_routes(
                df_routes, step_options['transition_duration_ms'],
                trail_length=step_options['trail_length'],
                on_complete=self.on_step_routes_complete,
                on_error=self.on_error)
        except:
            self.on_error()

    def on_step_routes_complete(self, start_time, electrode_ids):
        '''
        Callback function executed when all concurrent routes for a step have
        completed a single run.

        If repeats are requested, either through repeat counts or a repeat
        duration, *cycle* routes (i.e., routes that terminate at the start
        electrode) will repeat as necessary.
        '''
        step_options = self.get_step_options()
        step_duration_s = (datetime.now() -
                           self.step_start_time).total_seconds()
        if ((step_options['repeat_duration_s'] > 0 and step_duration_s <
             step_options['repeat_duration_s']) or
            (self.repeat_i + 1 < step_options['route_repeats'])):
            # Either repeat duration has not been met, or the specified number
            # of repetitions has not been met.  Execute another iteration of
            # the routes.
            self.repeat_i += 1
            df_routes = self.get_routes()
            self.route_controller.execute_routes(
                df_routes, step_options['transition_duration_ms'],
                trail_length=step_options['trail_length'],
                cyclic=True, acyclic=False,
                on_complete=self.on_step_routes_complete,
                on_error=self.on_error)
        else:
            logger.info('Completed routes (%s repeats in %ss)', self.repeat_i +
                        1, si_format(step_duration_s))
            # Transitions along all droplet routes have been processed.
            # Signal step has completed and reset plugin step state.
            emit_signal('on_step_complete', [self.name, None])

    def on_step_options_swapped(self, plugin, old_step_number, step_number):
        """
        Handler called when the step options are changed for a particular
        plugin.  This will, for example, allow for GUI elements to be
        updated based on step specified.

        Parameters:
            plugin : plugin instance for which the step options changed
            step_number : step number that the options changed for
        """
        logger.info('[on_step_swapped] old step=%s, step=%s', old_step_number,
                    step_number)
        self.kill_running_step()

    def on_step_removed(self, step_number, step):
        self.update_steps()

    def on_step_options_changed(self, plugin, step_number):
        self.update_steps()

    def on_step_swapped(self, old_step_number, step_number):
        """
        Handler called when the current step is swapped.
        """
        logger.info('[on_step_swapped] old step=%s, step=%s', old_step_number,
                    step_number)
        self.kill_running_step()
        self.get_routes()

    def on_step_inserted(self, step_number, *args):
        self.step_inserted(step_number)

    def step_inserted(self, step_number):
        app = get_app()
        logger.info('[on_step_inserted] current step=%s, created step=%s',
                    app.protocol.current_step_number, step_number)
        self.clear_routes(step_number=step_number)

    ###########################################################################
    # Step options dependent methods
    def update_protocol(self, protocol):
        app = get_app()

        for i, s in enumerate(protocol):

            step = app.protocol.steps[i]
            prevData = step.get_data(self.plugin_name)
            values = {}

            for k,v in prevData.iteritems():
                if k in s:
                    values[k] = s[k]

            step.set_data(self.plugin_name, values)
            emit_signal('on_step_options_changed', [self.plugin_name, i],
                        interface=IPlugin)

    def add_route(self, electrode_ids):
        '''
        Add droplet route.

        Args:

            electrode_ids (list) : Ordered list of identifiers of electrodes on
                route.
        '''
        drop_routes = self.get_routes()
        route_i = (drop_routes.route_i.max() + 1
                    if drop_routes.shape[0] > 0 else 0)
        drop_route = (pd.DataFrame(electrode_ids, columns=['electrode_i'])
                      .reset_index().rename(columns={'index': 'transition_i'}))
        drop_route.insert(0, 'route_i', route_i)
        drop_routes = drop_routes.append(drop_route, ignore_index=True)
        self.set_routes(drop_routes)
        return {'route_i': route_i, 'drop_routes': drop_routes}

    def clear_routes(self, electrode_id=None, step_number=None):
        '''
        Clear all drop routes for protocol step that include the specified
        electrode (identified by string identifier).
        '''
        step_options = self.get_step_options(step_number)

        if electrode_id is None:
            # No electrode identifier specified.  Clear all step routes.
            df_routes = RouteController.default_routes()
        else:
            df_routes = step_options['drop_routes']
            # Find indexes of all routes that include electrode.
            routes_to_clear = df_routes.loc[df_routes.electrode_i ==
                                            electrode_id, 'route_i']
            # Remove all routes that include electrode.
            df_routes = df_routes.loc[~df_routes.route_i
                                      .isin(routes_to_clear.tolist())].copy()
        step_options['drop_routes'] = df_routes
        self.set_step_values(step_options, step_number=step_number)
        self.get_routes()

    def get_routes(self, step_number=None):
        step_options = self.get_step_options(step_number=step_number)
        x = step_options.get('drop_routes',
                                RouteController.default_routes())
        msg = json.dumps(x, cls=PandasJsonEncoder)
        self.mqtt_client.publish('microdrop/droplet-planning-plugin/routes-set',
                                 msg, retain=True)
        return x

    def execute_routes(self, data):
        # TODO allow for passing of both electrode_id and route_i
        # Currently electrode_id only

        try:
            df_routes = self.get_routes()
            step_options = self.get_step_options()

            if 'transition_duration_ms' in data:
                transition_duration_ms = data['transition_duration_ms']
            else:
                transition_duration_ms = step_options['transition_duration_ms']

            if 'trail_length' in data:
                trail_length = data['trail_length']
            else:
                trail_length = step_options['trail_length']

            if 'route_i' in data:
                df_routes = df_routes.loc[df_routes.route_i == data['route_i']]
            elif 'electrode_i' in data:
                if data['electrode_i'] is not None:
                    routes_to_execute = df_routes.loc[df_routes.electrode_i ==
                                                      data['electrode_i'],
                                                      'route_i']
                    df_routes = df_routes.loc[df_routes.route_i
                                              .isin(routes_to_execute
                                                    .tolist())].copy()

            route_controller = RouteController(self)
            route_controller.execute_routes(df_routes, transition_duration_ms,
                                            trail_length=trail_length)
        except:
            logger.error(str(data), exc_info=True)

    def update_steps(self):
        app = get_app()
        num_steps = len(app.protocol.steps)

        protocol = []
        for i in range(num_steps):
            protocol.append(self.get_step_options(i))

        self.mqtt_client.publish('microdrop/droplet-planning-plugin/step-options',
                                  json.dumps(protocol, cls=PandasJsonEncoder),
                                  retain=True)

    def set_routes(self, df_routes, step_number=None):
        step_options = self.get_step_options(step_number=step_number)
        step_options['drop_routes'] = df_routes
        self.set_step_values(step_options, step_number=step_number)
コード例 #36
0
def test_scalar_set_default():
    el = Integer()
    el.set_default()
    assert el.value is None

    el = Integer(default=10)
    el.set_default()
    assert el.value == 10

    el = Integer(default_factory=lambda e: 20)
    el.set_default()
    assert el.value == 20
コード例 #37
0
    cols=COLS).using(label=L_('Subscriptions'),
                     optional=True,
                     separator='\n',
                     separator_regex=re.compile(r'[\r\n]+'))

Quicklinks = MyJoinedString.of(String).with_properties(
    widget=WIDGET_MULTILINE_TEXT, rows=ROWS,
    cols=COLS).using(label=L_('Quick Links'),
                     optional=True,
                     separator='\n',
                     separator_regex=re.compile(r'[\r\n]+'))

Search = Text.using(default=u'', optional=True).with_properties(
    widget=WIDGET_SEARCH, placeholder=L_("Search Query"))

_Integer = Integer.validated_by(Converted())

AnyInteger = _Integer.with_properties(widget=WIDGET_ANY_INTEGER)

Natural = AnyInteger.validated_by(ValueAtLeast(0))

SmallNatural = _Integer.with_properties(widget=WIDGET_SMALL_NATURAL)


class DateTimeUNIX(_DateTime):
    """
    A DateTime that uses a UNIX timestamp instead of datetime as internal
    representation of DateTime.
    """
    def serialize(self, value):
        """Serializes value to string."""
コード例 #38
0
#! -*- coding: utf-8 -*-
from flatland import Array, Boolean, Integer
from flatland.out import generic
from flatland.out.generic import Context

Unspecified = object()
Unique = object()
schema = Integer.named(u'number')
boolean_schema = Boolean.named(u'bool')
partial_anon_schema = Array.named(u'array').of(Integer)
full_anon_schema = Array.of(Integer)


def assert_bound_transform(fn, tagname, given, expected, **kw):
    return assert_transform(fn, tagname, given, expected, **kw)


def assert_unbound_transform(fn, tagname, given, expected, **kw):
    kw['bind'] = None
    return assert_transform(fn, tagname, given, expected, **kw)


def assert_transform(fn,
                     tagname,
                     given,
                     expected,
                     context=Unspecified,
                     bind=Unspecified,
                     contents=Unspecified,
                     expected_contents=Unspecified):
    if context is Unspecified:
コード例 #39
0
ファイル: test_dicts.py プロジェクト: orutherfurd/flatland
def test_dict_as_unicode():
    schema = Dict.of(Integer.named(u'x'), Integer.named(u'y'))
    el = schema({u'x': 1, u'y': 2})

    assert el.u in (u"{u'x': u'1', u'y': u'2'}", u"{u'y': u'2', u'x': u'1'}")
コード例 #40
0
ファイル: test_dicts.py プロジェクト: orutherfurd/flatland
def test_sparsedict_bogus_set_default():
    schema = SparseDict.using(minimum_fields='bogus').\
                        of(Integer.named(u'x'))
    el = schema()
    assert_raises(RuntimeError, el.set_default)
コード例 #41
0
 def adapt(self, value):
     try:
         return Integer.adapt(self, value)
     except:
         return None
コード例 #42
0
    def __init__(self, forms, enabled_attrs, show_ids=True, **kwargs):
        self.first_selected = True
        self._forms = forms.copy()
        row_id_properties = dict(editable=False)
        if not show_ids:
            row_id_properties['show_in_gui'] = False
        self._forms['__DefaultFields'] = \
            Form.of(Integer.named('id').using(default=0,
                                              properties=row_id_properties))

        self.uuid_mapping = dict([(name, uuid4().get_hex()[:10])
                                  for name in self._forms])
        self.uuid_reverse_mapping = dict([
            (v, k) for k, v in self.uuid_mapping.items()
        ])
        self._columns = []
        self._full_field_to_field_def = {}
        if not enabled_attrs:

            def enabled(form_name, field):
                return True
        else:

            def enabled(form_name, field):
                return field.name in enabled_attrs.get(form_name, {})

        # Make __DefaultFields.id the first column
        form_names = ['__DefaultFields'] + sorted(forms.keys())
        for form_name in form_names:
            form = self._forms[form_name]
            for field_name in form.field_schema:
                if all([
                        not form_name == '__DefaultFields',
                        not enabled(form_name, field_name)
                ]):
                    continue
                default_title = re.sub(r'_', ' ', field_name.name).capitalize()
                # Use custom column heading/title, if available.
                title = field_name.properties.get('title', default_title)
                prefix = self.field_set_prefix % self.uuid_mapping[form_name]
                name = '%s%s' % (prefix, field_name.name)
                val_type = get_type_from_schema(field_name)
                d = dict(attr=name,
                         type=val_type,
                         title=title,
                         resizable=True,
                         editable=True,
                         sorted=False)
                if field_name.properties.get('mappers', None):
                    d['mappers'] = deepcopy(field_name.properties['mappers'])
                    for m in d['mappers']:
                        m.attr = '%s%s' % (prefix, m.attr)
                if 'editable' in field_name.properties:
                    d['editable'] = field_name.properties['editable']
                if 'show_in_gui' in field_name.properties:
                    d['visible'] = field_name.properties['show_in_gui']
                if val_type == bool:
                    # Use checkbox for boolean cells
                    d['use_checkbox'] = True
                elif val_type == int:
                    # Use spinner for integer cells
                    d['use_spin'] = True
                    d['step'] = field_name.properties.get('step', 1)
                elif val_type == float:
                    # Use spinner for integer cells
                    d['use_spin'] = True
                    d['digits'] = field_name.properties.get('digits', 2)
                    d['step'] = field_name.properties.get('step', 0.1)
                self._columns.append(Column(**d))
                self._full_field_to_field_def[name] = field_name
        super(CombinedFields, self).__init__(self._columns, **kwargs)
        s = self.get_selection()
        # Enable multiple row selection
        s.set_mode(Gtk.SelectionMode.MULTIPLE)
        self.connect('item-changed', self._on_item_changed)
        self.connect('item-right-clicked', self._on_right_clicked)
        self.enabled_fields_by_form_name = enabled_attrs

        self.connect('item-added', lambda x, y: self.reset_row_ids())
        self.connect('item-inserted', lambda x, y, z: self.reset_row_ids())
        self.connect('item-removed', lambda x, y: self.reset_row_ids())
コード例 #43
0
    class BA3(B, A):
        field_schema = [Integer.named('b_member')]

        a_member = Integer