示例#1
0
 def test_use_machine_as_model(self):
     states = ['A', 'B', 'C', 'D']
     m = Machine(states=states, initial='A')
     m.add_transition('move', 'A', 'B')
     m.add_transition('move_to_C', 'B', 'C')
     m.move()
     self.assertEquals(m.state, 'B')
示例#2
0
 def test_send_event_data(self):
     states = ['A', 'B', 'C', 'D']
     s = Stuff()
     # First pass positional and keyword args directly to the callback
     m = Machine(model=s, states=states, initial='A', send_event=False)
     m.add_transition(
         trigger='advance', source='A', dest='B', before='set_message')
     s.advance(message='Hallo. My name is Inigo Montoya.')
     self.assertTrue(s.message.startswith('Hallo.'))
     # Now wrap arguments in an EventData instance
     m.send_event = True
     m.add_transition(
         trigger='advance', source='B', dest='C', before='extract_message')
     s.advance(message='You killed my father. Prepare to die.')
     self.assertTrue(s.message.startswith('You'))
class QueryDateRangeNarrower(object):

    states = ['init', 'whole', 'left', 'right', 'finished', 'asleep']
    OLDEST = 1
    NEWEST = 2

    def __init__(self, datasource, criteria, kind):

        self.datasource = datasource
        self.criteria = criteria
        self.kind = kind

        self.maxcount = 50
        self.hits = -1

        self.querycount = 0

        self.machine = Machine(model=self,
                               states=QueryDateRangeNarrower.states,
                               initial='asleep')

        self.machine.add_transition('start', '*', 'init', after='work')
        self.machine.add_transition('check',
                                    '*',
                                    'finished',
                                    conditions=['is_ready'])
        self.machine.add_transition('step',
                                    'init',
                                    'finished',
                                    conditions='is_century_out_of_bounds')
        self.machine.add_transition('step',
                                    'init',
                                    'whole',
                                    after=['runquery', 'check'])
        self.machine.add_transition('step',
                                    'whole',
                                    'init',
                                    conditions='no_hits',
                                    after='range_next_century')

        if self.kind == self.OLDEST:
            self.date_from = Arrow.fromdatetime(
                datetime.datetime(1800, 0o1, 0o1))
            self.date_to = Arrow.fromdatetime(datetime.datetime(1899, 12, 31))
            self.factor = +1

            self.machine.add_transition(
                'step',
                'whole',
                'left',
                unless='is_ready',
                after=['range_whole_left', 'runquery', 'check'])
            self.machine.add_transition(
                'step',
                'left',
                'right',
                conditions='no_hits',
                after=['range_left_right', 'runquery', 'check'])
            self.machine.add_transition('step',
                                        'left',
                                        'whole',
                                        unless='is_ready',
                                        after=['range_shrink'])
            self.machine.add_transition('step',
                                        'right',
                                        'whole',
                                        unless='is_ready',
                                        after=['range_shrink'])

        elif self.kind == self.NEWEST:
            self.date_from = Arrow.fromdatetime(
                datetime.datetime(2000, 0o1, 0o1))
            self.date_to = Arrow.utcnow()
            self.date_to += relativedelta(months=12 - self.date_to.month,
                                          days=31 - self.date_to.day)
            self.factor = -1

            self.machine.add_transition(
                'step',
                'whole',
                'right',
                unless='is_ready',
                after=['range_whole_right', 'runquery', 'check'])
            self.machine.add_transition(
                'step',
                'right',
                'left',
                conditions='no_hits',
                after=['range_right_left', 'runquery', 'check'])
            self.machine.add_transition('step',
                                        'right',
                                        'whole',
                                        unless='is_ready',
                                        after=['range_shrink'])
            self.machine.add_transition('step',
                                        'left',
                                        'whole',
                                        unless='is_ready',
                                        after=['range_shrink'])

        else:
            raise ValueError('kind must be self.OLDEST or self.NEWEST')

        self.delta = (self.date_to - self.date_from) / 2

    def runquery(self):
        criteria = self.criteria.copy()
        criteria['pubdate'] = 'within {date_from},{date_to}'.format(
            date_from=self.date_from.format('YYYY-MM-DD'),
            date_to=self.date_to.format('YYYY-MM-DD'))

        query = make_expression_filter({
            'datasource': self.datasource,
            'format': 'comfort',
            'criteria': criteria,
        })['expression']

        if self.datasource == 'ops':
            self.response, self.hits = query_ops(query, limit=self.maxcount)

        elif self.datasource == 'depatisnet':
            self.response, self.hits = query_depatisnet(query,
                                                        limit=self.maxcount)

        elif self.datasource == 'sip':
            self.response, self.hits = query_sip(query, limit=self.maxcount)

        else:
            raise ValueError('Data source "{0}" not implemented'.format(
                self.datasource))

        self.querycount += 1

    def no_hits(self):
        return self.hits == 0

    def is_ready(self):
        return self.hits > 0 and self.hits <= self.maxcount

    # for "oldest" searches
    def range_whole_left(self):
        self.date_to -= self.delta

    def range_left_right(self):
        self.date_from += self.delta
        self.date_to += self.delta

    # for "newest" searches
    def range_whole_right(self):
        self.date_from += self.delta

    def range_right_left(self):
        self.date_from -= self.delta
        self.date_to -= self.delta

    def range_shrink(self):
        self.delta /= 2

    def range_next_century(self):

        century = self.date_from.year / 100
        century += self.factor

        year_begin = century * 100 + 00
        year_end = century * 100 + 99

        self.date_from += relativedelta(years=year_begin - self.date_from.year,
                                        months=-self.date_from.month + 1,
                                        days=-self.date_from.day + 1)
        self.date_to += relativedelta(years=year_end - self.date_to.year,
                                      months=12 - self.date_to.month,
                                      days=31 - self.date_to.day)

    def is_century_out_of_bounds(self):
        return self.date_from.year > Arrow.utcnow(
        ).year or self.date_to.year < 1800

    def work(self):
        debug = False
        while True:
            if debug:
                print('-' * 42)
                print('state:', self.state)
                print('delta:', self.delta)
                print('querycount:', self.querycount)
            if self.state == 'finished' or self.querycount > 15:
                break
            self.step()