def convert_tzdatetime(value): # Note: use is __class__ since issubclass(datetime, date) if type(value) is date: value = todatetime(value) elif getattr(value, 'tzinfo', None): value = utcdatetime(value) return value
def parse_datetime(self, value, etype='Datetime'): """get a datetime or time from a string (according to etype) Datetime formatted as Date are accepted """ assert etype in ('Datetime', 'Date', 'Time'), etype # XXX raise proper validation error if etype == 'Datetime': format = self.property_value('ui.datetime-format') try: return todatetime(strptime(value, format)) except ValueError: pass elif etype == 'Time': format = self.property_value('ui.time-format') try: # (adim) I can't find a way to parse a time with a custom format date = strptime(value, format) # this returns a datetime return time(date.hour, date.minute, date.second) except ValueError: raise ValueError( self._('can\'t parse %(value)r (expected %(format)s)') % { 'value': value, 'format': format }) try: format = self.property_value('ui.date-format') dt = strptime(value, format) if etype == 'Datetime': return todatetime(dt) return todate(dt) except ValueError: raise ValueError( self._('can\'t parse %(value)r (expected %(format)s)') % { 'value': value, 'format': format })
def process_field_data(self, form, field): req = form._cw datestr = req.form.get(field.input_name(form, 'date')) if datestr: datestr = datestr.strip() if not datestr: return None try: date = todatetime(req.parse_datetime(datestr, 'Date')) except ValueError as exc: raise ProcessFormError(str(exc)) timestr = req.form.get(field.input_name(form, 'time')) if timestr: timestr = timestr.strip() if not timestr: return date try: time = req.parse_datetime(timestr, 'Time') except ValueError as exc: raise ProcessFormError(str(exc)) return date.replace(hour=time.hour, minute=time.minute, second=time.second)
def convert_datetime(value): # Note: use is __class__ since issubclass(datetime, date) if type(value) is date: value = todatetime(value) return value
def call(self, title=None): """Dumps a timetable from a resultset composed of a note (anything with start/stop) and a user (anything)""" self._cw.add_css('cubicweb.timetable.css') dates = {} users = [] users_max = {} # XXX: try refactoring with calendar.py:OneMonthCal for row in range(self.cw_rset.rowcount): task = self.cw_rset.get_entity(row, 0) icalendarable = task.cw_adapt_to('ICalendarable') if len(self.cw_rset[row] ) > 1 and self.cw_rset.description[row][1] == 'CWUser': user = self.cw_rset.get_entity(row, 1) else: user = ALL_USERS the_dates = [] if icalendarable.start and icalendarable.stop: if icalendarable.start.toordinal( ) == icalendarable.stop.toordinal(): the_dates.append(icalendarable.start) else: the_dates += date_range(icalendarable.start, icalendarable.stop + ONEDAY) elif icalendarable.start: the_dates.append(icalendarable.start) elif icalendarable.stop: the_dates.append(icalendarable.stop) for d in the_dates: d = todatetime(d) d_users = dates.setdefault(d, {}) u_tasks = d_users.setdefault(user, set()) u_tasks.add(task) task_max = users_max.setdefault(user, 0) if len(u_tasks) > task_max: users_max[user] = len(u_tasks) if user not in users: # keep original ordering users.append(user) if not dates: return date_min = min(dates) date_max = max(dates) #users = list(sorted(users, key=lambda u:u.login)) rows = [] # colors here are class names defined in cubicweb.css colors = ["col%x" % i for i in range(12)] next_color_index = 0 visited_tasks = {} # holds a description of a task for a user task_colors = {} # remember a color assigned to a task for date in date_range(date_min, date_max + ONEDAY): columns = [date] d_users = dates.get(date, {}) for user in users: # every user has its column "splitted" in at least MIN_COLS # sub-columns (for overlapping tasks) user_columns = [None] * max(MIN_COLS, users_max[user]) # every task that is "visited" for the first time # require a special treatment, so we put them in # 'postpone' postpone = [] for task in d_users.get(user, []): key = (task, user) if key in visited_tasks: task_descr = visited_tasks[key] user_columns[task_descr.column] = task_descr, False task_descr.lines += 1 else: postpone.append(key) for key in postpone: # to every 'new' task we must affect a color # (which must be the same for every user concerned # by the task) task, user = key for i, t in enumerate(user_columns): if t is None: if task in task_colors: color = task_colors[task] else: color = colors[next_color_index] next_color_index = (next_color_index + 1) % len(colors) task_colors[task] = color task_descr = _TaskEntry(task, color, i) user_columns[i] = task_descr, True visited_tasks[key] = task_descr break else: raise RuntimeError("is it possible we got it wrong?") columns.append(user_columns) rows.append(columns) widths = [len(col) for col in rows[0][1:]] self.w(u'<div class="section">') if title: self.w(u'<h4>%s</h4>\n' % title) self.w(u'<table class="listing timetable">') self.render_col_headers(users, widths) self.render_rows(rows) self.w(u'</table>') self.w(u'</div>\n')
def in_working_hours(self): """predicate returning True is the task is in working hours""" if todatetime(self.start).hour > 7 and todatetime(self.stop).hour < 20: return True return False