def do_GET(self): try: client_hostname = self.headers["Client-Hostname"] # get permission from C3Server if not self.server.get_serve_permission(client_hostname): # send 503 service unavailable response self.send_response(httplib.SERVICE_UNAVAILABLE, self.responses[httplib.OK][0]) msg = "Can't serve you. C3 told me not to." self.send_header("Content-Type", "text/plain") self.send_header("Content-Length", len(msg)) self.end_headers() self.wfile.write(msg) return # permission was granted! proceed # read parameters which are found as headers in the HTTP request cloudiness_forecast_time = self.headers["Cloudiness-Forecast-Time"] cloudiness_sample_size = self.headers["Cloudiness-Sample-Size"] sample_size = int(cloudiness_sample_size) forecast_dt = datetime.datetime.strptime(cloudiness_forecast_time, '%Y-%m-%dT%H:%M') if forecast_dt.hour == 23 and forecast_dt.minute == 45: pass # sample size defines how many surrounding images should be used # when doing the cloudiness calculation and finding an average if sample_size > 0: sample_times = date_helper.get_surrounding_datetimes_n_years( forecast_dt, constants.WTHR_IMG_FREQ_MINS, constants.WTHR_IMG_FREQ_MINS * sample_size, sample_size) # OLD VARIANT: ONLY SAMPLE SAME YEAR # sample_times = get_surrounding_datetimes(forecast_dt, # constants.WTHR_IMG_FREQ_MINS, # constants.WTHR_IMG_FREQ_MINS * sample_size) else: sample_times = [forecast_dt] sw = util.stopwatch() sw.start() # temporary dict to hold time/cloudiness key/value pairs t_c_temp_dict = {} # temporary dict to hold time/raw-image key/value pairs t_img_temp_dict = {} # for each sample time, check cache for cloudiness value # download image and calc if not there actual_image = None for t in sample_times: # Check cache. t_c_temp_dict[t] = self._getCachedCloudinessValue(t) if t_c_temp_dict[t] != None: continue # Cache hit! else: # No cigar. Have to download image and calculate. t_img_temp_dict[t] = self.server.dl_weather_image(t) if not t_img_temp_dict[t]: continue # couldn't get image if t == forecast_dt: actual_image = t_img_temp_dict[t] sw.stop() time_taken_imgdl = sw.getresult_ms() cloudiness_values = [] for c in t_c_temp_dict.itervalues(): if c != None: cloudiness_values.append(c) else: pass sw.start() # Calculate the cloudiness values for all images. img = None for t, img in t_img_temp_dict.iteritems(): if img: # Might be None, if the server replied 404 Not Found cloudiness_value = self.server.get_image_cloudiness(img) cloudiness_values.append(cloudiness_value) self._saveCloudinessValue(t, cloudiness_value) self._saveCloudyImage(cloudiness_value, img) sw.stop() time_taken_calc = sw.getresult_ms() if len(cloudiness_values) == 0: pass # the average cloudiness value cloudiness_value = float(sum(cloudiness_values) / len(cloudiness_values)) # TODO: find an image that matches the forecasted cloudiness value if not img: # first check image cache img = self._getCachedCloudyImage(cloudiness_value) if img: print "Reqtime: %s - Cloudy image cache hit!" % str(cloudiness_forecast_time) else: # actually have to download an image... while img == None: print "Reqtime: %s - Cache fail, having to DL..." % str(cloudiness_forecast_time) t = forecast_dt img = self.server.dl_weather_image(t) t = date_helper.add_minutes(t, constants.WTHR_IMG_FREQ_MINS) forecasted_image = img if not forecasted_image: print "I have no image to return!" raise Exception actual_cloudiness = self._getCachedCloudinessValue(forecast_dt) # in case of cache-hit, the actual image is not in memory if actual_image == None: sw.start() actual_image = self.server.dl_weather_image(forecast_dt) sw.stop() time_taken_imgdl += sw.getresult_ms() if actual_image == None: actual_image = self._getCachedCloudyImage(actual_cloudiness) if actual_image == None: actual_image = forecasted_image # send reponse back to client # the payload is a blob containing both images.. their sizes # defined in HTTP headers Blob1-Size and Blob2-Size self.send_response(httplib.OK, self.responses[httplib.OK][0]) self.send_header("Content-Type", "ela035/2ximageblob") self.send_header("Content-Length", len(forecasted_image) + len(actual_image)) self.send_header("Blob1-Size", len(forecasted_image)) self.send_header("Blob2-Size", len(actual_image)) self.send_header("Cloudiness-Forecast", str(cloudiness_value)) self.send_header("Actual-Cloudiness", str(actual_cloudiness)) self.send_header("Image-Download-Time", str(time_taken_imgdl)) self.send_header("Calc-Time", str(time_taken_calc)) self.end_headers() self.wfile.write(forecasted_image) self.wfile.write(actual_image) self.server.imgdltime = time_taken_imgdl self.server.cloudcalctime = time_taken_calc except Exception as e: print e msg = "Internal server error :-(" self.send_response(httplib.INTERNAL_SERVER_ERROR, self.responses[httplib.INTERNAL_SERVER_ERROR][0]) self.send_header("Content-Length", len(msg)) self.end_headers() self.wfile.write(msg)
''' Created on Mar 31, 2012 @author: erik ''' import date_helper import datetime import util if __name__ == '__main__': origin = datetime.datetime(2003, 3, 22, 12, 45) sw = util.stopwatch() sw.start() # get all times between origin and +-180 minutes at 15 minute steps # this will be a list of datetime objects datetimes = date_helper.get_surrounding_datetimes_n_years(origin, 15, 30, 1) sw.stop() for t in datetimes: print t print "testing get_datetime_from_isoformat..." print date_helper.get_datetime_from_isoformat(datetimes[0].isoformat()) print "Time spent: %f ms" % sw.getresult_ms()