Exemple #1
0
    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()