13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
14 # details. |
14 # details. |
15 # |
15 # |
16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """html calendar views |
18 """html timetable views""" |
19 |
19 |
20 """ |
20 __docformat__ = "restructuredtext en" |
|
21 _ = unicode |
21 |
22 |
22 from logilab.mtconverter import xml_escape |
23 from logilab.mtconverter import xml_escape |
23 from logilab.common.date import date_range, todatetime |
24 from logilab.common.date import ONEDAY, date_range, todatetime |
24 |
25 |
25 from cubicweb.interfaces import ITimetableViews |
26 from cubicweb.selectors import adaptable |
26 from cubicweb.selectors import implements |
27 from cubicweb.view import EntityView |
27 from cubicweb.view import AnyRsetView |
|
28 |
28 |
29 |
29 |
30 class _TaskEntry(object): |
30 class _TaskEntry(object): |
31 def __init__(self, task, color, column): |
31 def __init__(self, task, color, column): |
32 self.task = task |
32 self.task = task |
35 self.lines = 1 |
35 self.lines = 1 |
36 |
36 |
37 MIN_COLS = 3 # minimum number of task columns for a single user |
37 MIN_COLS = 3 # minimum number of task columns for a single user |
38 ALL_USERS = object() |
38 ALL_USERS = object() |
39 |
39 |
40 class TimeTableView(AnyRsetView): |
40 class TimeTableView(EntityView): |
41 __regid__ = 'timetable' |
41 __regid__ = 'timetable' |
42 title = _('timetable') |
42 title = _('timetable') |
43 __select__ = implements(ITimetableViews) |
43 __select__ = adaptable('ICalendarable') |
44 paginable = False |
44 paginable = False |
45 |
45 |
46 def call(self, title=None): |
46 def call(self, title=None): |
47 """Dumps a timetable from a resultset composed of a note (anything |
47 """Dumps a timetable from a resultset composed of a note (anything |
48 with start/stop) and a user (anything)""" |
48 with start/stop) and a user (anything)""" |
51 users = [] |
51 users = [] |
52 users_max = {} |
52 users_max = {} |
53 # XXX: try refactoring with calendar.py:OneMonthCal |
53 # XXX: try refactoring with calendar.py:OneMonthCal |
54 for row in xrange(self.cw_rset.rowcount): |
54 for row in xrange(self.cw_rset.rowcount): |
55 task = self.cw_rset.get_entity(row, 0) |
55 task = self.cw_rset.get_entity(row, 0) |
|
56 icalendarable = task.cw_adapt_to('ICalendarable') |
56 if len(self.cw_rset[row]) > 1: |
57 if len(self.cw_rset[row]) > 1: |
57 user = self.cw_rset.get_entity(row, 1) |
58 user = self.cw_rset.get_entity(row, 1) |
58 else: |
59 else: |
59 user = ALL_USERS |
60 user = ALL_USERS |
60 the_dates = [] |
61 the_dates = [] |
61 if task.start and task.stop: |
62 if icalendarable.start and icalendarable.stop: |
62 if task.start.toordinal() == task.stop.toordinal(): |
63 if icalendarable.start.toordinal() == icalendarable.stop.toordinal(): |
63 the_dates.append(task.start) |
64 the_dates.append(icalendarable.start) |
64 else: |
65 else: |
65 the_dates += date_range( task.start, task.stop ) |
66 the_dates += date_range(icalendarable.start, |
66 elif task.start: |
67 icalendarable.stop + ONEDAY) |
67 the_dates.append(task.start) |
68 elif icalendarable.start: |
68 elif task.stop: |
69 the_dates.append(icalendarable.start) |
69 the_dates.append(task.stop) |
70 elif icalendarable.stop: |
|
71 the_dates.append(icalendarable.stop) |
70 for d in the_dates: |
72 for d in the_dates: |
71 d = todatetime(d) |
73 d = todatetime(d) |
72 d_users = dates.setdefault(d, {}) |
74 d_users = dates.setdefault(d, {}) |
73 u_tasks = d_users.setdefault(user, set()) |
75 u_tasks = d_users.setdefault(user, set()) |
74 u_tasks.add( task ) |
76 u_tasks.add( task ) |