Example #1
0
    def get(self):

        # validate the request parameters
        devStoreKey = validateRequest(self.request, api_utils.GETROUTES)
        if devStoreKey is None:
            logging.debug("unable to validate the request parameters")
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.out.write(
                json.dumps(
                    api_utils.buildErrorResponse(
                        '-1', 'Illegal request parameters')))
            return

        logging.debug('getroutes request...  ')
        if self.request.get('force') is not '':
            refresh = True
        else:
            refresh = False

        if api_utils.afterHours() is True:
            # don't run these jobs during "off" hours
            json_response = api_utils.buildErrorResponse(
                '-1', 'The Metro service is not currently running')
        else:
            if refresh is True:
                json_response = getRoutes(refresh)

                # drop it into the memcache again
                memcache.set(api_utils.GETROUTES, json_response)
                logging.debug('---> storing in memcache')
            else:
                logging.debug('---> memcache hit')
                json_response = memcache.get(api_utils.GETROUTES)
                if json_response is None:
                    json_response = getRoutes(refresh)

                    # drop it into the memcache again
                    memcache.set(api_utils.GETROUTES, json_response)
                    logging.debug('---> storing in memcache')

            # record the API call for this devkey
            api_utils.recordDeveloperRequest(devStoreKey, api_utils.GETROUTES,
                                             self.request.query_string,
                                             self.request.remote_addr)

        #logging.debug('API: json response %s' % json_response);
        callback = self.request.get('callback')
        if callback is not '':
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.headers['Access-Control-Allow-Origin'] = '*'
            self.response.headers['Access-Control-Allow-Methods'] = 'GET'
            response = callback + '(' + json.dumps(json_response) + ');'
        else:
            self.response.headers['Content-Type'] = 'application/json'
            response = json_response

        self.response.out.write(response)
        stathat.apiStatCount()
Example #2
0
def validateRequest(request,type):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None,api_utils.GETSTOPS,request.query_string,request.remote_addr,'illegal developer key specified');
        return None

    return devStoreKey
Example #3
0
    def get(self):

        # validate the request parameters
        devStoreKey = validateRequest(self.request, api_utils.GETSTOPLOCATION)
        if devStoreKey is None:
            logging.debug("unable to validate the request parameters")
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.out.write(
                json.dumps(
                    api_utils.buildErrorResponse(
                        '-1', 'Illegal request parameters')))
            return

        # snare the inputs
        stopID = api_utils.conformStopID(self.request.get('stopID'))
        logging.debug('getstoplocation request parameters...  stopID %s' %
                      stopID)

        if api_utils.afterHours() is True:
            # don't run these jobs during "off" hours
            json_response = api_utils.buildErrorResponse(
                '-1', 'The Metro service is not currently running')
        elif stopID is not '':
            json_response = stopLocationRequest(stopID)
            api_utils.recordDeveloperRequest(devStoreKey, api_utils.GETSTOPS,
                                             self.request.query_string,
                                             self.request.remote_addr)
        else:
            logging.error("API: invalid request")
            json_response = api_utils.buildErrorResponse(
                '-1',
                'Invalid Request parameters. Did you forget to include a stpID?'
            )
            api_utils.recordDeveloperRequest(
                devStoreKey, api_utils.GETSTOPS, self.request.query_string,
                self.request.remote_addr, 'illegal query string combination')

        #logging.debug('API: json response %s' % json_response);
        # encapsulate response in json
        callback = self.request.get('callback')
        if callback is not '':
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.headers['Access-Control-Allow-Origin'] = '*'
            self.response.headers['Access-Control-Allow-Methods'] = 'GET'
            response = callback + '(' + json.dumps(json_response) + ');'
        else:
            self.response.headers['Content-Type'] = 'application/json'
            response = json.dumps(json_response)

        self.response.out.write(response)
        stathat.apiStatCount()
        # push event out to anyone watching the live board
        task = Task(url='/map/task', params={'stopID': stopID})
        task.add('eventlogger')
Example #4
0
def validateRequest(request, type):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        logging.debug('... illegal developer key %s' % request.get('key'))
        api_utils.recordDeveloperRequest(None, api_utils.GETSTOPS,
                                         request.query_string,
                                         request.remote_addr,
                                         'illegal developer key specified')
        return None

    if type == api_utils.GETSTOPS:
        routeID = request.get('routeID')
        destination = request.get('destination').upper()

        # a routeID is required
        if routeID is None or routeID is '':
            api_utils.recordDeveloperRequest(devStoreKey, type,
                                             request.query_string,
                                             request.remote_addr,
                                             'a routeID must be included')
            return None
        elif destination is not None and routeID is '':
            api_utils.recordDeveloperRequest(
                devStoreKey, type, request.query_string, request.remote_addr,
                'if a destination is specified, a routeID must be included')
            return None
    elif type == api_utils.GETSTOPLOCATION:
        stopID = api_utils.conformStopID(request.get('stopID'))
        if stopID == '' or stopID == '0' or stopID == '00':
            return None
    elif type == api_utils.GETNEARBYSTOPS:
        lat = request.get('lat')
        lon = request.get('lon')
        radius = request.get('radius')
        # lat/long is required
        if lat is None or lon is None:
            api_utils.recordDeveloperRequest(
                devStoreKey, type, request.query_string, request.remote_addr,
                'both latitude and longitude values must be specified')
            return None
        elif radius is not None and radius is not '' and radius > '5000':
            logging.error(
                'unable to validate getnearbystops call. illegal radius value of %s'
                % radius)
            api_utils.recordDeveloperRequest(devStoreKey, type,
                                             request.query_string,
                                             request.remote_addr,
                                             'radius must be less than 5,000')
            return None

    return devStoreKey
Example #5
0
    def get(self):

      # validate the request parameters
      devStoreKey = validateRequest(self.request,api_utils.GETROUTES)
      if devStoreKey is None:
          logging.debug("unable to validate the request parameters")
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.out.write(json.dumps(api_utils.buildErrorResponse('-1','Illegal request parameters')))
          return

      logging.debug('getroutes request...  ')
      if self.request.get('force') is not '':
          refresh = True
      else:
          refresh = False

      if api_utils.afterHours() is True:
          # don't run these jobs during "off" hours
	      json_response = api_utils.buildErrorResponse('-1','The Metro service is not currently running')
      else:
          if refresh is True:
              json_response = getRoutes(refresh)

              # drop it into the memcache again
              memcache.set(api_utils.GETROUTES, json_response)
              logging.debug('---> storing in memcache');
          else:
              logging.debug('---> memcache hit');
              json_response = memcache.get(api_utils.GETROUTES)
              if json_response is None:
                  json_response = getRoutes(refresh)

                  # drop it into the memcache again
                  memcache.set(api_utils.GETROUTES, json_response)
                  logging.debug('---> storing in memcache');


          # record the API call for this devkey
          api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETROUTES,self.request.query_string,self.request.remote_addr);

      #logging.debug('API: json response %s' % json_response);
      callback = self.request.get('callback')
      if callback is not '':
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.headers['Access-Control-Allow-Origin'] = '*'
          self.response.headers['Access-Control-Allow-Methods'] = 'GET'
          response = callback + '(' + json.dumps(json_response) + ');'
      else:
          self.response.headers['Content-Type'] = 'application/json'
          response = json_response

      self.response.out.write(response)
      stathat.apiStatCount()
Example #6
0
def validateRequest(request, type):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None, api_utils.GETSTOPS,
                                         request.query_string,
                                         request.remote_addr,
                                         'illegal developer key specified')
        return None

    return devStoreKey
Example #7
0
    def get(self):

        # validate the request parameters
        devStoreKey = validateRequest(self.request)
        if devStoreKey is None:
            logging.debug("unable to validate the request parameters")
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.out.write(
                json.dumps(
                    api_utils.buildErrorResponse(
                        '-1', 'Illegal request parameters')))
            return

        # snare the inputs
        routeID = self.request.get('routeID')
        logging.debug('getvehicles request parameters...  routeID %s' %
                      routeID)

        if api_utils.afterHours() is True:
            # don't run these jobs during "off" hours
            json_response = api_utils.buildErrorResponse(
                '-1', 'The Metro service is not currently running')
        elif routeID is not '':
            json_response = routeRequest(routeID)
            api_utils.recordDeveloperRequest(devStoreKey,
                                             api_utils.GETVEHICLES,
                                             self.request.query_string,
                                             self.request.remote_addr)
        else:
            logging.error("API: invalid request")
            json_response = api_utils.buildErrorResponse(
                '-1',
                'Invalid Request parameters. Did you forget to include a routeID?'
            )
            api_utils.recordDeveloperRequest(
                devStoreKey, api_utils.GETVEHICLES, self.request.query_string,
                self.request.remote_addr, 'illegal query string combination')

        #logging.debug('API: json response %s' % json_response);
        # encapsulate response in json
        callback = self.request.get('callback')
        if callback is not '':
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.headers['Access-Control-Allow-Origin'] = '*'
            self.response.headers['Access-Control-Allow-Methods'] = 'GET'
            response = callback + '(' + json.dumps(json_response) + ');'
        else:
            self.response.headers['Content-Type'] = 'application/json'
            response = json.dumps(json_response)

        self.response.out.write(response)
        stathat.apiStatCount()
def validateRequest(request):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None, api_utils.GETSTOPS, request.query_string, request.remote_addr, 'illegal developer key specified');
        return None

    routeID = request.get('routeID')
    if routeID is None or routeID is '':
        api_utils.recordDeveloperRequest(devStoreKey,type,request.query_string,request.remote_addr,'a routeID must be included');
        return None

    return devStoreKey
Example #9
0
def validateRequest(request):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None, api_utils.GETARRIVALS,
                                         request.query_string,
                                         request.remote_addr,
                                         'illegal developer key specified')
        return None
    stopID = request.get('stopID')
    routeID = request.get('routeID')
    vehicleID = request.get('vehicleID')

    # give up if someone asked for stop 0, which seems to be popular for some reason
    #logging.debug('validating stopID %s' % stopID);
    if stopID == '' or stopID is '0' or stopID is '0000':
        return None

    # a stopID or routeID is required
    if stopID is None and routeID is None:
        api_utils.recordDeveloperRequest(
            devStoreKey, api_utils.GETARRIVALS, request.query_string,
            request.remote_addr,
            'either a stopID or a routeID must be included')
        return None

    # the routeID requires either a vehicleID or stopID
    if routeID is not None:
        if vehicleID is None and stopID is None:
            api_utils.recordDeveloperRequest(
                devStoreKey, api_utils.GETARRIVALS, request.query_string,
                request.remote_addr,
                'if routeID is specified, either a vehicleID or stopID is required'
            )
            return None

    # the vehicleID requires a routeID
    if vehicleID is not None:
        if routeID is None:
            api_utils.recordDeveloperRequest(
                devStoreKey, api_utils.GETVEHICLE, request.query_string,
                request.remote_addr,
                'if a vehicleID is specified, you must include a routeID')
            return False

    # we've noticed some flagrant abuses of the API where the format
    # of the request parameters are just bogus. check those here
    if len(stopID) > 4:
        return None

    #logging.debug("successfully validated command parameters")
    return devStoreKey
    def get(self):
      
      # validate the request parameters
      devStoreKey = validateRequest(self.request,api_utils.GETSTOPLOCATION)
      if devStoreKey is None:
          logging.debug("unable to validate the request parameters")
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.out.write(json.dumps(api_utils.buildErrorResponse('-1','Illegal request parameters')))
          return
      
      # snare the inputs
      stopID = api_utils.conformStopID(self.request.get('stopID'))
      logging.debug('getstoplocation request parameters...  stopID %s' % stopID)
      
      if api_utils.afterHours() is True:
          # don't run these jobs during "off" hours
	      json_response = api_utils.buildErrorResponse('-1','The Metro service is not currently running')
      elif stopID is not '':
          json_response = stopLocationRequest(stopID)
          api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETSTOPS,self.request.query_string,self.request.remote_addr);
      else:
          logging.error("API: invalid request")
          json_response = api_utils.buildErrorResponse('-1','Invalid Request parameters. Did you forget to include a stpID?')
          api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETSTOPS,self.request.query_string,self.request.remote_addr,'illegal query string combination');

      #logging.debug('API: json response %s' % json_response);    
      # encapsulate response in json
      callback = self.request.get('callback')
      if callback is not '':
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.headers['Access-Control-Allow-Origin'] = '*'
          self.response.headers['Access-Control-Allow-Methods'] = 'GET'
          response = callback + '(' + json.dumps(json_response) + ');'
      else:
          self.response.headers['Content-Type'] = 'application/json'
          response = json.dumps(json_response)
      
      self.response.out.write(response)
      stathat.apiStatCount()
      # push event out to anyone watching the live board
      task = Task(url='/map/task', params={'stopID':stopID})
      task.add('eventlogger')
Example #11
0
def validateRequest(request):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None, api_utils.GETSTOPS,
                                         request.query_string,
                                         request.remote_addr,
                                         'illegal developer key specified')
        return None

    routeID = request.get('routeID')
    if routeID is None or routeID is '':
        api_utils.recordDeveloperRequest(devStoreKey, type,
                                         request.query_string,
                                         request.remote_addr,
                                         'a routeID must be included')
        return None

    return devStoreKey
Example #12
0
    def get(self):

        # validate the request parameters
        devStoreKey = validateRequest(self.request)
        if devStoreKey is None:
            logging.debug("unable to validate the request parameters")
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.out.write(json.dumps(api_utils.buildErrorResponse('-1','Illegal request parameters')))
            return

        # snare the inputs
        routeID = self.request.get('routeID')
        if len(routeID) == 1:
            routeID = "0" + routeID
        logging.debug('getvehicles request parameters...  routeID %s' % routeID)

        if api_utils.afterHours() is True:
            # don't run these jobs during "off" hours
            json_response = api_utils.buildErrorResponse('-1', 'The Metro service is not currently running')
        elif routeID is not '':
            json_response = routeRequest(routeID)
            api_utils.recordDeveloperRequest(devStoreKey, api_utils.GETVEHICLES, self.request.query_string, self.request.remote_addr);
        else:
            logging.error("API: invalid request")
            json_response = api_utils.buildErrorResponse('-1','Invalid Request parameters. Did you forget to include a routeID?')
            api_utils.recordDeveloperRequest(devStoreKey, api_utils.GETVEHICLES, self.request.query_string, self.request.remote_addr,'illegal query string combination');

        #logging.debug('API: json response %s' % json_response);
        # encapsulate response in json
        callback = self.request.get('callback')
        if callback is not '':
            self.response.headers['Content-Type'] = 'application/javascript'
            self.response.headers['Access-Control-Allow-Origin'] = '*'
            self.response.headers['Access-Control-Allow-Methods'] = 'GET'
            response = callback + '(' + json.dumps(json_response) + ');'
        else:
            self.response.headers['Content-Type'] = 'application/json'
            response = json.dumps(json_response)

        self.response.out.write(response)
        stathat.apiStatCount()
def validateRequest(request,type):
    
    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        logging.debug('... illegal developer key %s' % request.get('key'))
        api_utils.recordDeveloperRequest(None,api_utils.GETSTOPS,request.query_string,request.remote_addr,'illegal developer key specified');
        return None
    
    if type == api_utils.GETSTOPS:
        routeID = request.get('routeID')
        destination = request.get('destination').upper()
        
        # a routeID is required
        if routeID is None or routeID is '':
            api_utils.recordDeveloperRequest(devStoreKey,type,request.query_string,request.remote_addr,'a routeID must be included');
            return None
        elif destination is not None and routeID is '':
            api_utils.recordDeveloperRequest(devStoreKey,type,request.query_string,request.remote_addr,'if a destination is specified, a routeID must be included');
            return None
    elif type == api_utils.GETSTOPLOCATION:
        stopID = api_utils.conformStopID(request.get('stopID'))
        if stopID == '' or stopID == '0' or stopID == '00':
            return None            
    elif type == api_utils.GETNEARBYSTOPS:
        lat = request.get('lat')
        lon = request.get('lon')
        radius = request.get('radius')
        # lat/long is required
        if lat is None or lon is None:
            api_utils.recordDeveloperRequest(devStoreKey,type,request.query_string,request.remote_addr,'both latitude and longitude values must be specified');
            return None
        elif radius is not None and radius is not '' and radius > '5000':
            logging.error('unable to validate getnearbystops call. illegal radius value of %s' % radius)
            api_utils.recordDeveloperRequest(devStoreKey,type,request.query_string,request.remote_addr,'radius must be less than 5,000');
            return None

    return devStoreKey
Example #14
0
def validateRequest(request):

    # validate the key
    devStoreKey = api_utils.validateDevKey(request.get('key'))
    if devStoreKey is None:
        api_utils.recordDeveloperRequest(None,api_utils.GETARRIVALS,request.query_string,request.remote_addr,'illegal developer key specified');
        return None
    stopID = request.get('stopID')
    routeID = request.get('routeID')
    vehicleID = request.get('vehicleID')

    # give up if someone asked for stop 0, which seems to be popular for some reason
    #logging.debug('validating stopID %s' % stopID);
    if stopID == '' or stopID is '0' or stopID is '0000':
        return None

    # a stopID or routeID is required
    if stopID is None and routeID is None:
        api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETARRIVALS,request.query_string,request.remote_addr,'either a stopID or a routeID must be included');
        return None

    # the routeID requires either a vehicleID or stopID
    if routeID is not None:
        if vehicleID is None and stopID is None:
            api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETARRIVALS,request.query_string,request.remote_addr,'if routeID is specified, either a vehicleID or stopID is required');
            return None

    # the vehicleID requires a routeID
    if vehicleID is not None:
        if routeID is None:
            api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETVEHICLE,request.query_string,request.remote_addr,'if a vehicleID is specified, you must include a routeID');
            return False

    # we've noticed some flagrant abuses of the API where the format
    # of the request parameters are just bogus. check those here
    if len(stopID) > 4:
        return None

    #logging.debug("successfully validated command parameters")
    return devStoreKey
Example #15
0
    def get(self):
        start = time.time()
        # snare the inputs
        dev_key = self.request.get('key')
        stopID = api_utils.conformStopID(self.request.get('stopID'))
        routeID = self.request.get('routeID')
        vehicleID = self.request.get('vehicleID')
        #logging.debug('getarrivals request parameters...  stopID %s routeID %s vehicleID %s' % (stopID,routeID,vehicleID))

        self.request.registry['aggregated_results'] = []

        try:
            if api_utils.afterHours() is False:  # and dev_key != 'uwkiosk9':

                # validate the request parameters
                devStoreKey = validateRequest(self.request)
                if devStoreKey is None:
                    # filter out the kiosk errors from the log
                    if (not (dev_key == 'kiosk'
                             and self.request.get('stopID') == '')):
                        logging.error(
                            "failed to validate the request parameters")
                    self.response.headers[
                        'Content-Type'] = 'application/javascript'
                    self.response.out.write(
                        json.dumps(
                            api_utils.buildErrorResponse(
                                '-1',
                                'Unable to validate the request. There may be an illegal developer key.'
                            )))
                    return

                if stopID is not '' and routeID is '':
                    json_response = stopRequest(stopID, dev_key)
                    api_utils.recordDeveloperRequest(devStoreKey,
                                                     api_utils.GETARRIVALS,
                                                     self.request.query_string,
                                                     self.request.remote_addr)
                elif stopID is not '' and routeID is not '':
                    json_response = stopRouteRequest(stopID, routeID,
                                                     devStoreKey)
                    api_utils.recordDeveloperRequest(devStoreKey,
                                                     api_utils.GETARRIVALS,
                                                     self.request.query_string,
                                                     self.request.remote_addr)
                elif routeID is not '' and vehicleID is not '':
                    json_response = routeVehicleRequest(
                        routeID, vehicleID, devStoreKey)
                    api_utils.recordDeveloperRequest(devStoreKey,
                                                     api_utils.GETVEHICLE,
                                                     self.request.query_string,
                                                     self.request.remote_addr)
                else:
                    logging.debug("API: invalid request")
                    api_utils.recordDeveloperRequest(
                        devStoreKey, api_utils.GETARRIVALS,
                        self.request.query_string, self.request.remote_addr,
                        'illegal query string combination')
                    json_response = api_utils.buildErrorResponse(
                        '-1', 'Invalid Request parameters')

                # push event out to anyone watching the live board
                channels = memcache.get('channels')
                if channels is not None:
                    task = Task(url='/map/task', params={'stopID': stopID})
                    task.add('eventlogger')

                # stop statistics - DISABLED
                # if( "kiosk" not in dev_key ):
                #     task = Task(url='/stats/stop', params={'apikey':dev_key,'stop':stopID})
                #     task.add('stats')

            else:
                # don't run these jobs during "off" hours
                #logging.debug('shunted... off hour request')
                #if dev_key.find('kiosk') >= 0:
                #  json_response = api_utils.buildErrorResponse('-1','Kiosk requests no longer supported')
                #else:
                json_response = api_utils.buildErrorResponse(
                    '-1', 'The Metro service is not currently running')

            # encapsulate response in json or jsonp
            callback = self.request.get('callback')
            if callback is not '':
                self.response.headers[
                    'Content-Type'] = 'application/javascript'
                self.response.headers['Access-Control-Allow-Origin'] = '*'
                self.response.headers['Access-Control-Allow-Methods'] = 'GET'
                response = callback + '(' + json.dumps(json_response) + ');'
            else:
                self.response.headers['Content-Type'] = 'application/json'
                response = json.dumps(json_response)

            self.response.out.write(response)
        except DeadlineExceededError:
            self.response.clear()
            self.response.set_status(500)
            self.response.out.write(
                "This operation could not be completed in time...")

        # persist some statistics
        # stathat:
        if api_utils.afterHours() is False and dev_key != 'uwkiosk9':
            stathat.apiTimeStat(config.STATHAT_API_GETARRIVALS_TIME_KEY,
                                ((time.time() - start) * 1000))
            stathat.apiStatCount()
Example #16
0
    def get(self):
      start = time.time()
      # snare the inputs
      dev_key = self.request.get('key')
      stopID = api_utils.conformStopID(self.request.get('stopID'))
      routeID = self.request.get('routeID')
      vehicleID = self.request.get('vehicleID')
      #logging.debug('getarrivals request parameters...  stopID %s routeID %s vehicleID %s' % (stopID,routeID,vehicleID))

      self.request.registry['aggregated_results'] = []

      try:
          if api_utils.afterHours() is False:  # and dev_key != 'uwkiosk9':

              # validate the request parameters
              devStoreKey = validateRequest(self.request)
              if devStoreKey is None:
                  # filter out the kiosk errors from the log
                  if( not (dev_key == 'kiosk' and self.request.get('stopID') == '') ):
                      logging.error("failed to validate the request parameters")
                  self.response.headers['Content-Type'] = 'application/javascript'
                  self.response.out.write(json.dumps(api_utils.buildErrorResponse('-1','Unable to validate the request. There may be an illegal developer key.')))
                  return

              if stopID is not '' and routeID is '':
                  json_response = stopRequest(stopID, dev_key)
                  api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETARRIVALS,self.request.query_string,self.request.remote_addr);
              elif stopID is not '' and routeID is not '':
                  json_response = stopRouteRequest(stopID, routeID, devStoreKey)
                  api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETARRIVALS,self.request.query_string,self.request.remote_addr);
              elif routeID is not '' and vehicleID is not '':
                  json_response = routeVehicleRequest(routeID, vehicleID, devStoreKey)
                  api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETVEHICLE,self.request.query_string,self.request.remote_addr);
              else:
                  logging.debug("API: invalid request")
                  api_utils.recordDeveloperRequest(devStoreKey,api_utils.GETARRIVALS,self.request.query_string,self.request.remote_addr,'illegal query string combination');
                  json_response = api_utils.buildErrorResponse('-1','Invalid Request parameters')

              # push event out to anyone watching the live board
              channels = memcache.get('channels')
              if channels is not None:
                  task = Task(url='/map/task', params={'stopID':stopID})
                  task.add('eventlogger')

              # stop statistics - DISABLED
              # if( "kiosk" not in dev_key ):
              #     task = Task(url='/stats/stop', params={'apikey':dev_key,'stop':stopID})
              #     task.add('stats')

          else:
              # don't run these jobs during "off" hours
              #logging.debug('shunted... off hour request')
              #if dev_key.find('kiosk') >= 0:
              #  json_response = api_utils.buildErrorResponse('-1','Kiosk requests no longer supported')
              #else:
              json_response = api_utils.buildErrorResponse('-1','The Metro service is not currently running')

          # encapsulate response in json or jsonp
          callback = self.request.get('callback')
          if callback is not '':
              self.response.headers['Content-Type'] = 'application/javascript'
              self.response.headers['Access-Control-Allow-Origin'] = '*'
              self.response.headers['Access-Control-Allow-Methods'] = 'GET'
              response = callback + '(' + json.dumps(json_response) + ');'
          else:
              self.response.headers['Content-Type'] = 'application/json'
              response = json.dumps(json_response)

          self.response.out.write(response)
      except DeadlineExceededError:
          self.response.clear()
          self.response.set_status(500)
          self.response.out.write("This operation could not be completed in time...")

      # persist some statistics
      # stathat:
      if api_utils.afterHours() is False and dev_key != 'uwkiosk9':
        stathat.apiTimeStat(config.STATHAT_API_GETARRIVALS_TIME_KEY,((time.time()-start)*1000))
        stathat.apiStatCount()