def fill_gaps_generator(interval, start_time, stop_time, query, *columns): """Generate a timeseries sequence with a value for every sample expected. Iterate backwards in steps specified by interval from the most recent date (stop_time) to the oldest (start_time) and pull the columns listed out of query. If the query doesn't have data for a time slice, fill the gap with an appropriate number of zeroes. """ iterator = PeekableIterator(query) step = timedelta_by_name(interval) current_slice = stop_time while current_slice > start_time: row = iterator.peek() if row and row.date == current_slice: yield current_slice, tuple(getattr(row, c) for c in columns) iterator.next() else: yield current_slice, tuple(0 for c in columns) # moving backwards a month isn't a fixed timedelta -- special case it if interval != "month": current_slice -= step else: current_slice = decrement_month(current_slice)
def make_period_link(interval, date): date = date.replace(tzinfo=g.tz) # won't be necessary after tz fixup if interval == "month": if date.month != 12: end = date.replace(month=date.month + 1) else: end = date.replace(month=1, year=date.year + 1) else: end = date + timedelta_by_name(interval) query = urllib.urlencode({ "syntax": "cloudsearch", "restrict_sr": "on", "sort": "top", "q": "timestamp:{:d}..{:d}".format(int(epoch_seconds(date)), int(epoch_seconds(end))), }) return "/r/%s/search?%s" % (c.site.name, query)
def get_time_points(interval, start_time=None, stop_time=None): """Return time points for given interval type. Time points are in reverse chronological order to match the sort of queries this will be used with. If start_time and stop_time are not specified they will be picked based on the interval. """ def truncate_datetime(dt): dt = dt.replace(minute=0, second=0, microsecond=0) if interval in ("day", "month"): dt = dt.replace(hour=0) if interval == "month": dt = dt.replace(day=1) return dt if start_time and stop_time: start_time, stop_time = sorted([start_time, stop_time]) # truncate stop_time to an actual traffic time point stop_time = truncate_datetime(stop_time) else: # the stop time is the most recent slice-time; get this by truncating # the appropriate amount from the current time stop_time = datetime.datetime.utcnow() stop_time = truncate_datetime(stop_time) # then the start time is easy to work out range = time_range_by_interval[interval] start_time = stop_time - range step = timedelta_by_name(interval) current_time = stop_time time_points = [] while current_time >= start_time: time_points.append(current_time) if interval != 'month': current_time -= step else: current_time = decrement_month(current_time) return time_points
def points_for_interval(interval): """Calculate the number of data points to render for a given interval.""" range = time_range_by_interval[interval] interval = timedelta_by_name(interval) return range.total_seconds() / interval.total_seconds()