Esempio n. 1
0
    def execute_request(self, request):
        instruction = request.get('inst')
        now_string = request.get('now', None)
        if now_string:
            now = cet_from_string(now_string)
            test_file = request.get('file', 'ignore')
        else:
            now = now_cet()
            test_file = None

        if instruction == 'avt':
            if self.answer_avt(now):
                increase_counter('req_avt_answered')
                self.perform_avt(now, test_file)
            else:
                increase_counter('req_avt_denied')

        elif instruction == 'prio':
            if self.answer_prio(now):
                increase_counter('req_prio_answered')
                self.perform_avt(now, test_file)
            else:
                increase_counter('req_prio_denied')

        elif instruction == 'check':
            mission_id = request.get('sender')
            exp_s = request.get('expected')
            if exp_s:
                expected = cet_from_string(exp_s)
            else:
                expected = now_cet() + timedelta(days=1)
            self.perform_check(mission_id, now, expected, test_file)

        elif instruction == 'console':
            self.perform_avt(now, test_file)
Esempio n. 2
0
    def get(self):
        increase_counter('req_trajectory')
        origin_id = self.request.get('from')
        if not self.validateID(origin_id): return
        destination_id = self.request.get('to')
        if not self.validateID(destination_id): return

        time_string = self.request.get('start', None)
        if time_string is None:
            start_time = now_cet() - timedelta(hours=1)
        else:
            if not self.validateDatetime(time_string): return
            start_time = cet_from_string(time_string)

        span_string = self.request.get('span', None)
        if span_string is None:
            time_span = timedelta(hours=3)
        else:
            if not self.validateDigit(span_string): return
            time_span = timedelta(hours=int(span_string))

        output_string = json.dumps(
            self.trajectory_dict(origin_id, destination_id, start_time,
                                 time_span))
        self.response.out.write(output_string)
Esempio n. 3
0
 def next_stop_index(self, now=None):
     if not now:
         now = now_cet()
     for index in range(len(self.stops)):
         if now < self.stops[index].est_departure:
             return index
     return None
Esempio n. 4
0
    def test_odids(self):

        # FRS 10.4 setting originID and destinationID

        # 1) Creating the dictionary
        mission = TAMission.new('nl.1234')
        self.assertEqual(mission.odIDs_dictionary, {'d': [None, None]})

        # 2) Reading and writing
        mission.nominalDate = now_cet().date()
        mission.odIDs_dictionary['d'] = ['nl.asd', 'nl.ehv']
        mission.origin_id = 'nl.asd'
        mission.destination_id = 'nl.ehv'
        self.assertFalse(mission.needs_datastore_put)
        mission.put()
        mission = TAMission.get('nl.1234')
        self.assertEqual(mission.origin_id, 'nl.asd')
        self.assertEqual(mission.destination_id, 'nl.ehv')
        self.assertEqual(mission.get_odIDs_string(0), 'nl.asd-nl.ehv')
        self.assertEqual(len(mission.odIDs_dictionary), 1)

        mission.set_odIDs_string(5, 'nl.asd-nl.ht')
        mission.set_odIDs_string(6, '-')
        self.assertTrue(mission.needs_datastore_put)
        self.assertEqual(mission.get_odIDs_for_weekday(5), ['nl.asd', 'nl.ht'])
        self.assertEqual(mission.get_odIDs_for_weekday(6), [None, None])
        self.assertEqual(len(mission.odIDs_dictionary), 3)

        # 3) Optimizing the dictionary
        for weekday in range(6):
            mission.set_odIDs_string(weekday, 'nl.asd-nl.mt')
        self.assertEqual(len(mission.odIDs_dictionary), 8)
        mission.optimize_odIDs_dictionary()
        self.assertEqual(len(mission.odIDs_dictionary), 2)
        self.assertTrue(mission.needs_datastore_put)
Esempio n. 5
0
 def activate_mission(self, now=None):
     if now is None:
         now = now_cet()
     if self.offset is None:
         self.offset = time(0)
         self.needs_datastore_put = True
     self.nominalDate = now.date()
     if self.destination_id is None:
         self.stops = []
     else:
         self.awake_stops()
         self.check_mission_announcements(now)
Esempio n. 6
0
 def get(self):
     user = users.get_current_user()
     if user:
         logging.info('stats request by logged in user: %s' %
                      user.nickname())
     else:
         logging.info('stats request by anonymous user')
     now_string = self.request.get('now')
     if now_string:
         now = cet_from_string(now_string)
     else:
         now = now_cet()
     self.response.out.write(json.dumps(TASeries.statistics(now)))
Esempio n. 7
0
    def test_object_creation(self):
        now = now_cet()
        agent = TSStationAgent.get('nl.test')
        logging.info('New agent: %s' % agent)
        agent.updated = now
        agent.cache_set()

        agent = TSStationAgent.get('nl.test')
        self.assertEqual(agent.id_, 'nl.test')
        self.assertEqual(agent.code, 'test')
        self.assertEqual(agent.country, 'nl')
        self.assertEqual(agent.updated, now)
        logging.info('Updated agent: %s' % agent)
Esempio n. 8
0
 def delete_point(self, station_id):
     expired_point = self.point_for_station(station_id)
     if expired_point:
         logging.info('Delete point %s' % station_id)
         tasks = []
         issue_time_cet = now_cet()
         for mission_id in self.all_mission_ids(Direction.up) + self.all_mission_ids(Direction.down):
             issue_time_cet += timedelta(seconds=config.INTERVAL_BETWEEN_UPDATE_MSG)
             tasks.append(self.stop_task(TAStop.revoked_stop(mission_id, station_id), issue_time_cet))
         issue_tasks(tasks)
         expired_point.delete()
         self.reset_points()
     else:
         logging.warning('Point %s could not be found for deletion' % station_id)
Esempio n. 9
0
 def statistics(cls, now=None):
     if now is None:
         now = now_cet()
     status_hist = {}
     delay_hist = {}
     for seriesID in TASeries.all_ids():
         series = TASeries.get(seriesID)
         for mission_id in series.current_mission_ids(Direction.up, now) + series.current_mission_ids(Direction.down, now):
             mission = TAMission.get(mission_id)
             status, delay = mission.status_at_time(now)
             data = MissionStatuses.s[status]
             status_hist[data] = status_hist.get(data, 0) + 1
             if status == MissionStatuses.running:
                 data = '%.0f' % delay
                 delay_hist[data] = delay_hist.get(data, 0) + 1
     return {'status': status_hist, 'delay': delay_hist, 'counter': counter_dict()}
Esempio n. 10
0
    def get(self):
        increase_counter('req_departures')
        series_id = self.request.get('series')
        if not self.validateID(series_id):
            self.reject()
            return
        origin_id = self.request.get('from')
        if not self.validateID(origin_id):
            self.reject()
            return

        direction_string = self.request.get('dir')
        if direction_string == 'up':
            direction = Direction.up
        elif direction_string == 'down':
            direction = Direction.down
        else:
            self.reject()
            return

        time_string = self.request.get('start', None)
        if time_string is None:
            start_time = now_cet() - timedelta(hours=1)
        else:
            if not self.validateDatetime(time_string): return
            start_time = cet_from_string(time_string)

        span_string = self.request.get('span', None)
        if span_string is None:
            time_span = timedelta(hours=3)
        else:
            if not self.validateDigit(span_string): return
            time_span = timedelta(hours=int(span_string))

        series = TASeries.get(series_id)
        if not series:
            self.reject()
            return
        output_string = json.dumps(
            self.departures_dict(series, origin_id, direction, start_time,
                                 time_span))
        self.response.out.write(output_string)
Esempio n. 11
0
    def status_at_time(self, now=None):
        if len(self.stops) == 0:
            return MissionStatuses.inactive, 0.0

        if now is None:
            now = now_cet()
        if now > self.est_arrival_cet:
            return MissionStatuses.arrived, self.last_stop.delay_dep

        index = self.next_stop_index(now)
        stop = self.stops[index]
        if stop.status == StopStatuses.canceled:
            return MissionStatuses.canceled, stop.delay_dep
        if index == 0:
            if stop.status == StopStatuses.announced:
                return MissionStatuses.announced, stop.delay_dep
            else:
                return MissionStatuses.inactive, 0.0

        return MissionStatuses.running, stop.delay_dep
Esempio n. 12
0
    def perform(self):
        instruction = self.request.get('inst')

        if instruction == 'fetch':
            if self.resource:
                self.resource.import_schedule()
                self.response.out.write('<a href=\"/console/series?id=%s\">terug naar serie</a>' % self.resource.id)
            else:
                TASeries.import_xml('series.data/series.xml')
                self.redirect('/console/series')
            return

        if not self.resource:
            logging.warning('Resource not found.')
            return

        if instruction == 'new_day':
            now_string = self.request.get('now')
            if now_string:
                now = cet_from_string(self.request.get('now'))
            else:
                now = now_cet()
            self.resource.activate_new_day(now)

        elif instruction == 'delete_point':
            sender = self.request.get('sender')
            self.resource.delete_point(sender)
            self.response.out.write('<a href=\"/console/series?id=%s\">terug naar serie</a>' % self.resource.id)

        elif instruction == 'optimize_odids':
            changed_missions = []
            for mission in self.resource.up_missions + self.resource.down_missions:
                mission.optimize_odIDs_dictionary()
                if mission.needs_datastore_put:
                    changed_missions.append(mission)
            memcache.set_multi(TAMission.dictionary_from_list(changed_missions), namespace='TAMission')
            db.put(changed_missions)
            self.response.out.write('<a href=\"/console/missions?kind=pattern&series=%s\">terug naar serie</a>' %
                                    self.resource.id)
Esempio n. 13
0
    def current_mission_ids(self, direction, now=None):
        if now is None:
            now = now_cet()
        if direction == Direction.up:
            start_time = now - timedelta(minutes=(self.last_point.upArrival + 30))
            end_time = now - timedelta(minutes=self.first_point.upDeparture)
        else:
            start_time = now - timedelta(minutes=(self.first_point.downArrival + 30))
            end_time = now - timedelta(minutes=self.last_point.downDeparture)
        min_time = (now - timedelta(hours=3)).replace(hour=0, minute=0, second=0)
        if start_time < min_time: start_time = min_time
        max_time = min_time.replace(hour=23, minute=59, second=59)
        if end_time > max_time: end_time = max_time

        source = self.mission_lists[direction]
        start_index = bisect.bisect_left(source, (start_time.time(), 0))
        end_index = bisect.bisect_right(source, (end_time.time(), 999999), lo=start_index)
        output = []
        for index in range(start_index, end_index):
            offset, number = source[index]
            output.append('%s.%d' % (self.country, number))

        return output
Esempio n. 14
0
 def perform(self):
     instruction = self.request.get('inst')
     if instruction == 'check':
         self.resource.check_mission_announcements(now_cet())
Esempio n. 15
0
    def update_stop(self, updated):
        now = updated.now
        if now is None:
            now = now_cet()
        status, delay = self.status_at_time(now)
        if status == MissionStatuses.arrived:
            logging.info('Update was ignored because mission has already arrived')
            return

        changes = False
        small_changes = False
        self.issue_time = now
        index = self.index_for_stop(updated)
        if index is not None:
            existing = self.stops[index]
            self.tasks = []

            if existing.status != updated.status:
                logging.info('Change status at %s from %s to %s.' % (existing.station_id,
                                                                     StopStatuses.s[existing.status],
                                                                     StopStatuses.s[updated.status]))
                if updated.status == StopStatuses.revoked:
                    self.remove_stop(index)
                    existing = None
                    changes = True
                else:
                    if existing.status == StopStatuses.planned and updated.status == StopStatuses.announced:
                        small_changes = True
                    elif existing.status == StopStatuses.altDestination and updated.status == StopStatuses.announced:
                        self.reset_destination()
                        changes = True
                    else:
                        if updated.status == StopStatuses.canceled:
                            self.check_for_canceled(index - 1)
                            self.check_for_canceled(index + 1)
                        elif existing.status == StopStatuses.canceled:
                            self.check_for_uncanceled(index - 1)
                            self.check_for_uncanceled(index + 1)
                        changes = True
                    existing.status = updated.status

            if existing is not None:
                if existing.delay_dep != updated.delay_dep:
                    logging.info('Change delay at %s from %.1f to %.1f.' %
                                 (existing.station_id, existing.delay_dep, updated.delay_dep))
                    next_index = self.next_stop_index(now)
                    if index == next_index:
                        increasing = bool(existing.delay_dep < updated.delay_dep)
                        self.update_delay(index, updated.delay_dep, increasing)
                        self.schedule_more_updates(updated, now)
                    else:
                        if next_index is not None and existing.delay_dep == 0:
                            next_stop = self.stops[next_index]
                            self.issue_time += timedelta(seconds=config.INTERVAL_BETWEEN_UPDATE_MSG)
                            self.tasks.append(self.instruction_task(next_stop.station_url, 'prio', self.issue_time))
                        existing.delay_dep = updated.delay_dep
                    changes = True

                if existing.platform != updated.platform and updated.platform is not None:
                    logging.info('Change platform at %s from %s to %s.' %
                                 (existing.station_id, existing.platform, updated.platform))
                    existing.platform = updated.platform
                    changes = True
                    if existing.platformChange != updated.platformChange:
                        existing.platformChange = updated.platformChange

                if existing.destination != updated.destination and updated.destination is not None:
                    logging.info('Change destination at %s from %s to %s.' %
                                 (existing.station_id, existing.destination, updated.destination))
                    existing.destination = updated.destination
                    changes = True
                    self.update_destination(updated.destination)

                if existing.alteredDestination != updated.alteredDestination:
                    logging.info('Change altered destination at %s from %s to %s.' %
                                 (existing.station_id, existing.alteredDestination, updated.alteredDestination))
                    if updated.alteredDestination is None:
                        self.reset_destination()
                    else:
                        self.alter_destination(updated.alteredDestination)
                    existing.alteredDestination = updated.alteredDestination
                    changes = True

                if existing.departure != updated.departure and updated.departure is not None:
                    logging.info('Change departure at %s from %s to %s.' %
                                 (existing.station_id, existing.departure.strftime('%H:%M'), updated.departure.strftime('%H:%M')))
                    logging.info('%s ==> %s' % (existing.departure, updated.departure))
                    delta = updated.departure - existing.departure
                    existing.arrival += delta
                    existing.departure = updated.departure
                    changes = True

            issue_tasks(self.tasks)
            self.tasks = None

        else:
            if updated.status == StopStatuses.announced or updated.status == StopStatuses.extra:
                self.anterior_stops(updated)
                changes = True
        if changes:
            increase_counter('mission_changes')
            self.put()
        else:
            if small_changes:
                increase_counter('mission_small_changes')
                self.cache_set()
            else:
                increase_counter('mission_no_changes')
Esempio n. 16
0
    def test_activate_mission(self):
        """
        FRS 10.5 Activating a mission and maintaining its status

        """
        # Load sample data:
        TSStation.update_stations('TestTAMission.data/stations.xml')
        TASeries.import_xml('TestTAMission.data/series.xml')

        taskq = self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME)

        # FRS 10.5.1 If not specified, activate_mission must set nominalDate to the current date
        now = now_cet().replace(hour=2)
        mission = TAMission.get('nl.3046')
        mission.activate_mission()
        self.assertEqual(mission.nominalDate, now.date())
        taskq.FlushQueue('default')

        # FRS 10.5.2/3 activate_mission must generate origin_id, destination_id and stops
        test_set = ((mark_cet(datetime(2013, 2, 24, 2)), None,
                     0), (mark_cet(datetime(2013, 2, 18, 2)), 'nl.asd', 5),
                    (mark_cet(datetime(2013, 2, 19, 2)), 'nl.amr', 8))
        for (testDate, destination, nr_of_stops) in test_set:
            mission.activate_mission(testDate)
            self.assertEqual(mission.destination_id, destination)
            self.assertEqual(len(mission.stops), nr_of_stops)
        mission.put()
        self.assertEqual(mission.origin_id, 'nl.ah')
        self.assertEqual(mission.last_stop.arrival_string, '15:48')

        # FRS 10.5.4 activated stops must get 'planned' status, last stop 'finalDestination'
        for index in range(0, 6):
            self.assertEqual(mission.stops[index].status, StopStatuses.planned)
        self.assertEqual(mission.stops[7].status,
                         StopStatuses.finalDestination)

        # FRS 10.5.5 TAMission must queue a check-task while awaking a mission.
        tasks = taskq.GetTasks('default')
        self.assertEqual(len(tasks), 2)
        self.assertEqual(tasks[1]['url'], '/TAMission/nl.3046')
        self.assertEqual(tasks[1]['name'], '19_1231_xx_check_3046')
        taskq.FlushQueue('default')

        # FRS 10.5.6 Mission must check announcement of stops
        check_time = mark_cet(datetime(2013, 2, 19, 13, 41, 22))
        mission.stops[0].status = StopStatuses.announced
        mission.check_mission_announcements(check_time)
        tasks = taskq.GetTasks('default')
        self.assertEqual(len(tasks), 2)
        self.assertEqual(tasks[0]['url'], '/agent/station/nl.ed')
        self.assertEqual(tasks[0]['name'], '19_1241_25_check_3046')
        self.assertEqual(tasks[1]['url'], '/TAMission/nl.3046')
        self.assertEqual(tasks[1]['name'], '19_1246_xx_check_3046')
        taskq.FlushQueue('default')

        check_time = mark_cet(datetime(2013, 2, 19, 14, 02, 22))
        mission.stops[0].status = StopStatuses.planned
        mission.stops[1].status = StopStatuses.announced
        mission.stops[2].status = StopStatuses.announced
        mission.stops[3].status = StopStatuses.announced
        mission.stops[4].status = StopStatuses.announced
        mission.check_mission_announcements(check_time)
        tasks = taskq.GetTasks('default')
        self.assertEqual(len(tasks), 1)
        self.assertEqual(tasks[0]['url'], '/TAMission/nl.3046')
        self.assertEqual(tasks[0]['name'], '19_1348_xx_check_3046')

        # FRS 10.5.7 Mission must provide status and delay
        (status,
         delay) = mission.status_at_time(mark_cet(datetime(2013, 2, 19, 14,
                                                           0)))
        self.assertEqual(status, MissionStatuses.inactive)
        self.assertEqual(delay, 0)
        mission.first_stop.status = StopStatuses.announced
        (status,
         delay) = mission.status_at_time(mark_cet(datetime(2013, 2, 19, 14,
                                                           0)))
        self.assertEqual(delay, 0)
        self.assertEqual(status, MissionStatuses.announced)
        (status, delay) = mission.status_at_time(
            mark_cet(datetime(2013, 2, 19, 14, 30)))
        self.assertEqual(status, MissionStatuses.running)
        self.assertEqual(delay, 0)
        (status, delay) = mission.status_at_time(
            mark_cet(datetime(2013, 2, 19, 15, 49)))
        self.assertEqual(mission.est_arrival_cet,
                         mark_cet(datetime(2013, 2, 19, 15, 48)))
        self.assertEqual(status, MissionStatuses.arrived)
        self.assertEqual(MissionStatuses.s[status], 'arrived')
        self.assertEqual(delay, 0)