Ejemplo n.º 1
0
Archivo: api.py Proyecto: jrenaut/bafs
 def history(self, date, lat=None, lon=None, us_city=None):
     
     latlon_location_param = None
     us_city_location_param = None
     
     if lat and lon:
         latlon_location_param = '{0},{1}'.format(lat,lon)
     
     # Try for US city first, since this will be more reusable
     if us_city:
         # Split on comma to extract state
         if us_city.count(',') != 1:
             self.log.info("Unable to parse city/state for us city: {0}".format(us_city))
         else:
             city_parts = [part.strip() for part in us_city.split(',')]
             if len(city_parts[-1]) > 2: # US states are 2-chars
                 self.log.info("Doesn't look like a US city (state component > 2 chars): {0}".format(us_city))
             else:
                 us_city_location_param = city_parts[-1] + "/" + city_parts[0].replace(' ', '_')
     
     # Check both for cache, starting with more specific one
     for lp in (latlon_location_param, us_city_location_param):
         if lp is not None:
             data = self._check_cache(lp, date)
             if data:
                 break
     
     if data is None:
         if not self.cache_only:
             # Attempt to fetch for real (and cache), giving preference to the less specific 
             # for the sake of better reusability
             for lp in (us_city_location_param, latlon_location_param):
                 if lp is not None:
                     try:
                         res = self.get(date.strftime('history_%Y%m%d'), 'q', lp)
                     except Fault:
                         self.log.info("Server fault trying to fetch weather for {0},{1}".format(lp, date))
                         continue
                     else:
                         break
             else:
                 # We tried all param options but each had an error
                 raise NoDataFound("Unable to retrieve weather for lat/lon={0}, us_city={1}, date={2}".format((lat,lon), us_city, date))
             
             # res should be defined if we get this far.
             data = res.json()
             self._write_cache(lp, date, data)
         else:
             raise NoDataFound("cache_only=True and no cached data found for lat/lon={0}, us_city={1}, date={2}".format((lat,lon), us_city, date))
     
     try:
         history_data = HistoryDay.from_json(data['history'])
     except:
         self.log.exception("Unable to parse data: {0!r}".format(data))
         raise
     
     return history_data
Ejemplo n.º 2
0
    def history(self, date, lat=None, lon=None, us_city=None):

        latlon_location_param = None
        us_city_location_param = None

        if lat and lon:
            latlon_location_param = '{0},{1}'.format(lat, lon)

        # Try for US city first, since this will be more reusable
        if us_city:
            # Split on comma to extract state
            if us_city.count(',') != 1:
                self.log.info("Unable to parse city/state for us city: {0}".format(us_city))
            else:
                state_code = None
                city_parts = [part.strip() for part in us_city.split(',')]
                if len(city_parts[-1]) > 2:  # US states are 2-chars
                    if city_parts[-1] in state_name_to_abbrev_map:
                        state_code = state_name_to_abbrev_map[city_parts[-1]]
                    else:
                        self.log.debug("State len > 2 and not in name -> abbrev map: {0!r}".format(city_parts[-1]))
                else:
                    state_code = city_parts[-1]

                if state_code:
                    us_city_location_param = state_code + "/" + city_parts[0].replace(' ', '_')
                else:
                    self.log.info("Unable to parse US state from {0!r}.".format(us_city))

        # Check both for cache, starting with more specific one
        data = None
        for lp in (latlon_location_param, us_city_location_param):
            if lp is not None:
                data = self._check_cache(lp, date)
                if data:
                    break

        if data is None:
            if not self.cache_only:
                # Attempt to fetch for real (and cache), giving preference to the less specific 
                # for the sake of better reusability
                for lp in (us_city_location_param, latlon_location_param):
                    if lp is not None:
                        try:
                            res = self.get(date.strftime('history_%Y%m%d'), 'q', lp)
                        except Fault:
                            self.log.info("Server fault trying to fetch weather for {0},{1}".format(lp, date))
                            continue
                        else:
                            data = res.json()
                            if 'history' in data and data['history'].get('observations'): # Do not break if we don't have a valid JSON response
                                break
                else:
                    # We tried all param options but each had an error
                    raise NoDataFound(
                        "Unable to retrieve weather for lat/lon={0}, us_city={1}, date={2}".format((lat, lon), us_city,
                                                                                                   date))
                # data should be non-null if we get here.
                self._write_cache(lp, date, data)
            else:
                raise NoDataFound(
                    "cache_only=True and no cached data found for lat/lon={0}, us_city={1}, date={2}".format((lat, lon),
                                                                                                             us_city,
                                                                                                             date))

        try:
            history_data = HistoryDay.from_json(data['history'])
        except:
            self.log.exception("Unable to parse data: {0!r}".format(data))
            raise

        return history_data