def get_timeline_data(self, data_date): interval_data = {} min_time = None min_hour = None max_time = None max_hour = None user_intervals = Interval.user_intervals(self.request.user) y, m, d = data_date.year, data_date.month, data_date.day tz = data_date.tzinfo min_datetime = datetime(y, m, d, 0, 0, 0, 0, tz) max_datetime = datetime(y, m, d, 23, 59, 59, 999999, tz) intervals = ( user_intervals .filter(start__range=(min_datetime, max_datetime)) .order_by('start') ) nowtz = now().astimezone(tz=tz) for interval in intervals: root_cat = interval.timer.category.root_parent.name start = interval.start.astimezone(tz=tz) end = interval.end.astimezone(tz=tz) if interval.end else nowtz if min_time is None or start < min_time: min_time = start if max_time is None or (end and end > max_time): max_time = end if root_cat not in interval_data: interval_data[root_cat] = { 'category_name': root_cat, 'intervals': [], } interval_data[root_cat]['intervals'].append({ 'interval_id': interval.id, 'timer_id': interval.timer.id, 'timer_name': interval.timer.name, 'start': start, 'end': end, }) if min_time is None: min_hour = time(8, 0, 0, 0) else: h, m, s, ms = [ getattr(min_time, x) for x in ['hour', 'minute', 'second', 'microsecond'] ] min_hour = time(h, 0, 0, 0) if max_time is None: max_hour = time(17, 0, 0, 0) else: # cap at midnight hour_later = max([max_time, max_time + timedelta(hours=1)]) # TODO: handle intervals extending past midnight... h, m, s, ms = [ getattr(hour_later, x) for x in ['hour', 'minute', 'second', 'microsecond'] ] max_hour = time(h, 0, 0, 0) return { 'interval_data': interval_data, 'min_hour': min_hour, 'max_hour': max_hour, }
def intervals(request): report_date = utils.get_report_date(request) year, month, day = report_date.year, report_date.month, report_date.day tz = report_date.tzinfo nowtz = now().astimezone(tz=tz) is_today = utils.date_is_today(report_date) root_categories = Category.objects.filter(user=request.user, parent=None) category_width = _get_category_width(root_categories.count()) user_intervals = Interval.user_intervals(request.user) def timedelta_height(td): hours = td.total_seconds() / 3600 height = PX_PER_HOUR * hours return int(height) min_datetime = datetime(year, month, day, 0, 0, 0, 0, tz) max_datetime = datetime(year, month, day, 23, 59, 59, 0, tz) all_intervals = user_intervals.filter( start__range=(min_datetime, max_datetime), ).order_by('start') if all_intervals.count() > 0: min_interval_time = all_intervals[0].start.astimezone(tz=tz) max_interval_time = all_intervals.latest('start').start.astimezone(tz=tz) if max_interval_time < nowtz: max_interval_time = nowtz else: min_interval_time = datetime(year, month, day, 8, 0, 0, 0, tz) max_interval_time = datetime(year, month, day, 18, 0, 0, 0, tz) def time_top(dt): temp_min_time = min_interval_time.replace(minute=0, second=0) offset = dt - temp_min_time return timedelta_height(offset) time_cells = [] for hour in range(min_interval_time.hour, max_interval_time.hour+1): start_time = datetime(year, month, day, hour, 0, 0, 0, tz) an_hour = timedelta(hours=1) time_cells.append({ 'height': timedelta_height(an_hour), 'top': time_top(start_time), 'value': start_time.strftime(TIME_FORMAT), 'classes': 'time-cell', }) if is_today: time_cells.append({ 'height': 1, 'top': time_top(nowtz), 'value': '', 'classes': 'current-time', }) root_category_cells = [] for cat in root_categories: interval_list = [] for interval in all_intervals: if interval.timer.category.root_parent == cat: interval_list.append(interval) cells = [] for interval in interval_list: start = interval.start.astimezone(tz=tz).strftime(TIME_FORMAT) end = '[active]' if interval.end is not None: end = interval.end.astimezone(tz=tz).strftime(TIME_FORMAT) title = '{0} ({1}-{2})'.format( interval.timer.hierarchy_display, start, end) cells.append({ 'height': timedelta_height(interval.length), 'top': time_top(interval.start.astimezone(tz=tz)), 'interval': interval, 'timer': interval.timer, 'title': title, 'start': start, 'end': end, }) root_category_cells.append((cat, cells)) context = { 'report_date': report_date, 'category_width': category_width, 'total_height': timedelta_height(max_interval_time - min_interval_time), 'time_cells': time_cells, 'root_category_cells': root_category_cells, } context = ReportsContext( request, context, ) return render_to_response('reports/intervals.html', {}, context)