1 ############################################################################
2 # Copyright (C) 2005 by Reithinger GmbH
5 # This file is part of faces.
7 # faces is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # faces is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the
19 # Free Software Foundation, Inc.,
20 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ############################################################################
23 import faces.pcalendar as pcal
24 import matplotlib.cbook as cbook
29 class TimeScale(object):
30 def __init__(self, calendar):
31 self.data_calendar = calendar
32 self._create_chart_calendar()
33 self.now = self.to_num(self.data_calendar.now)
36 def to_datetime(self, xval):
37 return xval.to_datetime()
40 def to_num(self, date):
41 return self.chart_calendar.WorkingDate(date)
44 def is_free_slot(self, value):
45 dt1 = self.chart_calendar.to_starttime(value)
46 dt2 = self.data_calendar.to_starttime\
47 (self.data_calendar.from_datetime(dt1))
51 def is_free_day(self, value):
52 dt1 = self.chart_calendar.to_starttime(value)
53 dt2 = self.data_calendar.to_starttime\
54 (self.data_calendar.from_datetime(dt1))
55 return dt1.date() != dt2.date()
58 def _create_chart_calendar(self):
59 dcal = self.data_calendar
60 ccal = self.chart_calendar = pcal.Calendar()
61 ccal.minimum_time_unit = 1
63 #pad worktime slots of calendar (all days should be equally long)
64 slot_sum = lambda slots: sum(map(lambda slot: slot[1] - slot[0], slots))
65 day_sum = lambda day: slot_sum(dcal.get_working_times(day))
67 max_work_time = max(map(day_sum, range(7)))
69 #working_time should have 2/3
70 sum_time = 3 * max_work_time / 2
72 #now create timeslots for ccal
73 def create_time_slots(day):
74 src_slots = dcal.get_working_times(day)
75 slots = [0, src_slots, 24*60]
76 slots = tuple(cbook.flatten(slots))
77 slots = zip(slots[:-1], slots[1:])
79 #balance non working slots
80 work_time = slot_sum(src_slots)
81 non_work_time = sum_time - work_time
83 non_slots = filter(lambda s: s not in src_slots, slots)
84 non_slots = map(lambda s: (s[1] - s[0], s), non_slots)
89 for l, s in non_slots:
90 delta = non_work_time / (len(non_slots) - i)
92 non_work_time -= delta
93 slots.append((s[0], s[0] + delta))
96 slots.extend(src_slots)
100 min_delta = sys.maxint
102 slots = create_time_slots(i)
103 ccal.working_times[i] = slots
104 min_delta = min(min_delta, min(map(lambda s: s[1] - s[0], slots)))
106 ccal._recalc_working_time()
108 self.slot_delta = min_delta
109 self.day_delta = sum_time
110 self.week_delta = ccal.week_time
113 _default_scale = TimeScale(pcal._default_calendar)