def getDayNames(locale=None): """TODO :param locale: the current locale (e.g: en, en_us, it)""" locale = (locale or DEFAULT_LOCALE).replace('-', '_') d = dict([(v.lower(), k) for k, v in dates.get_day_names(width='wide', locale=locale).items()]) d.update([(v.lower(), k) for k, v in dates.get_day_names(width='abbreviated', locale=locale).items()]) return d
def getDayNames(locale=None): """add??? :param locale: ???add. Default value is ``None`` :returns: add??? """ locale = (locale or DEFAULT_LOCALE).replace('-', '_') d = dict([(v.lower(), k) for k, v in dates.get_day_names(width='wide', locale=locale).items()]) d.update([(v.lower(), k) for k, v in dates.get_day_names(width='abbreviated', locale=locale).items()]) return d
def getDayNames(locale=None): """add??? :param locale: ???add. Default value is ``None`` :returns: add??? """ locale = (locale or DEFAULT_LOCALE).replace('-', '_') d = dict([ (v.lower(), k) for k, v in dates.get_day_names(width='wide', locale=locale).items() ]) d.update([(v.lower(), k) for k, v in dates.get_day_names(width='abbreviated', locale=locale).items()]) return d
def yearly_calendar(year, lang, project): ret = [] year_path = YEAR_PATH.format(year=year, lang=lang, project=project) for month in next(os.walk(year_path))[1]: month = int(month) month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) mname = month_name[month] mdata = { 'month_name': mname, 'month': month, 'year': year, 'weekdays': { 'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6] } } mdata['dates'] = monthly_calendar(year, month, lang, project) ret.append(mdata) ret.reverse() return ret
def update_month(query_date, lang, project): year = query_date.year month = query_date.month month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) data = {'dir_depth': '../' * 4, 'month_name': month_name[month], 'project': project.capitalize(), 'full_lang': LOCAL_LANG_MAP[lang], 'prev_month': check_month(query_date, 1, lang, project), 'next_month': check_month(query_date, -1, lang, project), 'year': year, 'meta': {'generated': datetime.utcnow().isoformat()}, 'weekdays': {'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6]}} data['dates'] = monthly_calendar(year, month, lang, project) month_index_path = MONTH_INDEX_PATH.format(lang=lang, project=project, year=year, month=month) month_index = pjoin(month_index_path, 'index.html') month_template = choose_template(template=MONTH_INDEX_TMPL, lang=lang) save_rendered(month_index, month_template, data) return data
def yearly_calendar(year, lang, project): ret = [] year_path = YEAR_PATH.format(year=year, lang=lang, project=project) for root, dirs, files in os.walk(year_path): for month in sorted(dirs, key=int): month = int(month) month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) mname = month_name[month] mdata = {'month_name': mname, 'month': month, 'year': year, 'local_year': int_to_local_str(year, locale=lang), 'weekdays': {'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6]}} mdata['dates'] = monthly_calendar(year, month, lang, project) ret.append(mdata) ret.reverse() return ret
def yearly_calendar(year, lang, project): ret = [] year_path = YEAR_PATH.format(year=year, lang=lang, project=project) for root, dirs, files in os.walk(year_path): for month in sorted(dirs, key=int): month = int(month) month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) mname = month_name[month] mdata = { 'month_name': mname, 'month': month, 'year': year, 'local_year': int_to_local_str(year, locale=lang), 'weekdays': { 'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6] } } mdata['dates'] = monthly_calendar(year, month, lang, project) ret.append(mdata) ret.reverse() return ret
def update_month(query_date, lang, project): year = query_date.year month = query_date.month month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) data = { "dir_depth": "../" * 4, "month_name": month_name[month], "project": project.capitalize(), "full_lang": LOCAL_LANG_MAP[lang], "prev_month": check_month(query_date, 1, lang, project), "next_month": check_month(query_date, -1, lang, project), "year": year, "meta": {"generated": datetime.utcnow().isoformat()}, "weekdays": { "mon": weekdays[0], "tues": weekdays[1], "wed": weekdays[2], "thurs": weekdays[3], "fri": weekdays[4], "sat": weekdays[5], "sun": weekdays[6], }, } data["dates"] = monthly_calendar(year, month, lang, project) month_index_path = MONTH_INDEX_PATH.format(lang=lang, project=project, year=year, month=month) month_index = pjoin(month_index_path, "index.html") month_template = choose_template(template=MONTH_INDEX_TMPL, lang=lang) save_rendered(month_index, month_template, data) return data
def tt_bottom(self, bottom, wkdlist): bottom.horizontalSlider(value='^.zoom', minimum=.2, maximum=3, intermediateChanges=True, width='15em', float='right') bottom.data('.zoom', 1) btn = bottom.button( '!!Configuration', action='SET .layoutregions.left?show=!GET .layoutregions.left?show', float='left') fb = bottom.formbuilder(cols=7, border_spacing='2px', datapath='.conf.dayrow.day', float='left') weekdays = dates.get_day_names(width='wide', locale=self.locale.replace('-', '_')) for k in wkdlist: fb.checkbox(value='^.show', default_value=True, label=weekdays[k], datapath='.%i' % k, _set_display='.dayrow_wd%i:#?"block":"none"' % k) bottom.div(float='left').dock(id='tt_footer', background='transparent')
def yearly_calendar(year, lang, project): ret = [] year_path = YEAR_PATH.format(year=year, lang=lang, project=project) for month in next(os.walk(year_path))[1]: month = int(month) month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) mname = month_name[month] mdata = { "month_name": mname, "month": month, "year": year, "weekdays": { "mon": weekdays[0], "tues": weekdays[1], "wed": weekdays[2], "thurs": weekdays[3], "fri": weekdays[4], "sat": weekdays[5], "sun": weekdays[6], }, } mdata["dates"] = monthly_calendar(year, month, lang, project) ret.append(mdata) ret.reverse() return ret
def update_month(query_date, lang, project): year = query_date.year month = query_date.month month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) data = {'dir_depth': '../' * 4, 'month_name': month_name[month], 'project': project.capitalize(), 'full_lang': LOCAL_LANG_MAP[lang], 'prev_month': check_month(query_date, 1, lang, project), 'next_month': check_month(query_date, -1, lang, project), 'year': year, 'local_year': int_to_local_str(year, locale=lang), 'meta': {'generated': datetime.utcnow().isoformat()}, 'weekdays': {'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6]}} data['dates'] = monthly_calendar(year, month, lang, project) month_index_path = MONTH_INDEX_PATH.format(lang=lang, project=project, year=year, month=month) month_index = pjoin(month_index_path, 'index.html') month_template = choose_template(template=MONTH_INDEX_TMPL, lang=lang) save_rendered(month_index, month_template, data) return data
def tt_left(self, bc, wkdlist): center = bc.contentPane(region='center') fb = center.formbuilder(cols=2, border_spacing='2px', datapath='.conf.dayrow.day') weekdays = dates.get_day_names(width='wide', locale=self.locale.replace('-', '_')) for k in wkdlist: fb.div(background='^.color', lbl=weekdays[k], datapath='.%i' % k, border='1px solid black', baseClass='no_background', height='12px', width='12px', connectedMenu='tt_colorPaletteMenu', _set_background_color='.dayrow_wd%i:"#"' % k) fb = center.formbuilder(cols=1, border_spacing='2px', width='80%') fb.horizontalSlider(value='^.conf.dayrow.height', lbl='Height', minimum=50, maximum=100, intermediateChanges=True, _set_height='.dayrow:#+"px"', _set_font_size='.daylabel_day:#-30+"px"') fb.horizontalSlider(value='^.conf.labelcolumn.width', lbl='Daylabel', minimum=30, maximum=100, intermediateChanges=True, _set_width='.labelcolumn:#+"px"', _set_left='.contentcolumn:#+"px"')
def expires_header(self, when): # FIXME: strftime returns localized month and day names but here we should use C locale # it's not possible to change locale for only this operation so we need our own lookup # table here return when.strftime("%(day)s, %%d %(month)s %%Y %%H:%%M:%%S GMT" % \ { 'day': get_day_names('abbreviated', locale='en_US')[when.weekday()].encode('utf-8'), 'month': get_month_names('abbreviated', locale='en_US')[when.month].encode('utf-8') })
def get_day_names(self, width='wide', context='format'): """Return the day names for the specified format In: - ``width`` -- 'wide', 'abbreviated' or 'narrow' - ``context`` -- either 'format' or 'stand-alone' Return: - the day names """ return dates.get_day_names(width, context, self)
def tt_bottom(self, bottom, wkdlist): bottom.horizontalSlider(value='^.zoom', minimum=.2, maximum=3, intermediateChanges=True, width='15em', float='right') bottom.data('.zoom', 1) btn = bottom.button('!!Configuration', action='SET .layoutregions.left?show=!GET .layoutregions.left?show', float='left') fb = bottom.formbuilder(cols=7, border_spacing='2px', datapath='.conf.dayrow.day', float='left') weekdays = dates.get_day_names(width='wide', locale=self.locale.replace('-', '_')) for k in wkdlist: fb.checkbox(value='^.show', default_value=True, label=weekdays[k], datapath='.%i' % k, _set_display='.dayrow_wd%i:#?"block":"none"' % k) bottom.div(float='left').dock(id='tt_footer', background='transparent')
def get_day_names_jquery_ui(req): """Get the day names for the jQuery UI datepicker library""" locale = req.lc_time if locale == 'iso8601': locale = req.locale if babel and locale: day_names = {} for width in ('wide', 'abbreviated', 'narrow'): names = get_day_names(width, locale=locale) day_names[width] = [names[(i + 6) % 7] for i in xrange(7)] return day_names return { 'wide': ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'), 'abbreviated': ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'), 'narrow': ('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'), }
def get_day_names(self, width='wide', context='format'): """Return the day names for the specified format >>> Locale('en', 'US').get_day_names('wide')[1] u'Tuesday' >>> Locale('es').get_day_names('abbreviated')[1] u'mar' >>> Locale('de', 'DE').get_day_names('narrow', context='stand-alone')[1] u'D' In: - ``width`` -- 'wide', 'abbreviated' or 'narrow' - ``context`` -- either 'format' or 'stand-alone' Return: - the day names """ return dates.get_day_names(width, context, self)
def yearly_calendar(year, lang, project): ret = [] year_path = YEAR_PATH.format(year=year, lang=lang, project=project) for month in next(os.walk(year_path))[1]: month = int(month) month_name = get_month_names(locale=lang) weekdays = get_day_names(locale=lang) mname = month_name[month] mdata = {'month_name': mname, 'month': month, 'year': year, 'weekdays': {'mon': weekdays[0], 'tues': weekdays[1], 'wed': weekdays[2], 'thurs': weekdays[3], 'fri': weekdays[4], 'sat': weekdays[5], 'sun': weekdays[6]}} mdata['dates'] = monthly_calendar(year, month, lang, project) ret.append(mdata) ret.reverse() return ret
def test_get_day_names(): assert dates.get_day_names('wide', locale='en_US')[1] == u'Tuesday' assert dates.get_day_names('abbreviated', locale='es')[1] == u'mar.' de = dates.get_day_names('narrow', context='stand-alone', locale='de_DE') assert de[1] == u'D'
def test_get_day_names(): assert dates.get_day_names('wide', locale='en_US')[1] == u'Tuesday' assert dates.get_day_names('short', locale='en_US')[1] == u'Tu' assert dates.get_day_names('abbreviated', locale='es')[1] == u'mar.' de = dates.get_day_names('narrow', context='stand-alone', locale='de_DE') assert de[1] == u'D'
def expand_macro(self, formatter, name, arguments): """Returns macro content.""" env = self.env req = formatter.req tz = req.tz # Parse arguments from macro invocation. args, kwargs = parse_args(arguments, strict=False) # Enable week number display regardless of argument position. week_pref = "w" in args and args.pop(args.index("w")) week_pref = week_pref and week_pref or kwargs.get("w") week_start = None week_num_start = None # Parse per-instance week calculation rules, if available. if week_pref: if ":" not in week_pref: # Treat undelimitted setting as week start. week_pref += ":" w_start, wn_start = week_pref.split(":") try: week_start = int(w_start) except ValueError: week_start = None else: week_start = week_start > -1 and week_start < 7 and week_start or None try: week_num_start = int(wn_start) except ValueError: week_num_start = None else: week_num_start = week_num_start in (1, 4, 7) and week_num_start or None # Respect user's locale, if available. try: locale = Locale.parse(str(req.locale)) except (AttributeError, UnknownLocaleError): # Attribute 'req.locale' vailable since Trac 0.12. locale = None if has_babel: if locale: if not locale.territory: # Search first locale, which has the same `language` and # territory in preferred languages. for l in req.languages: l = l.replace("-", "_").lower() if l.startswith(locale.language.lower() + "_"): try: l = Locale.parse(l) if l.territory: locale = l break # first one rules except UnknownLocaleError: pass if not locale.territory and locale.language in LOCALE_ALIASES: locale = Locale.parse(LOCALE_ALIASES[locale.language]) else: # Default fallback. locale = Locale("en", "US") env.log.debug("Locale setting for wiki calendar: %s" % locale.get_display_name("en")) if not week_start: if week_pref and week_pref.lower().startswith("iso"): week_start = 0 week_num_start = 4 elif has_babel: week_start = locale.first_week_day else: import calendar week_start = calendar.firstweekday() # ISO calendar will remain as default. if not week_num_start: if week_start == 6: week_num_start = 1 else: week_num_start = 4 env.log.debug( "Effective settings: first_week_day=%s, " "1st_week_of_year_rule=%s" % (week_start, week_num_start) ) # Find year and month of interest. year = req.args.get("year") # Not clicked on any previous/next button, next look for macro args. if not year and len(args) >= 1 and args[0] != "*": year = args[0] year = year and year.isnumeric() and int(year) or None month = req.args.get("month") # Not clicked on any previous/next button, next look for macro args. if not month and len(args) >= 2 and args[1] != "*": month = args[1] month = month and month.isnumeric() and int(month) or None now = datetime.now(tz) # Force offset from start-of-day to avoid a false 'today' marker, # but use it only on request of different month/year. now.replace(second=1) today = None if month and month != now.month: today = now.replace(month=month) if year and year != now.year: today = today and today.replace(year=year) or now.replace(year=year) # Use current month and year, if nothing else has been requested. if not today: today = now.replace(hour=0, minute=0, second=0, microsecond=0) showbuttons = True if len(args) >= 3 or kwargs.has_key("nav"): try: showbuttons = kwargs["nav"] in _TRUE_VALUES except KeyError: showbuttons = args[2] in _TRUE_VALUES wiki_page_format = "%Y-%m-%d" if len(args) >= 4 and args[3] != "*" or kwargs.has_key("wiki"): try: wiki_page_format = str(kwargs["wiki"]) except KeyError: wiki_page_format = str(args[3]) # Support relative paths in macro arguments for wiki page links. wiki_page_format = resolve_relative_name(wiki_page_format, formatter.resource.id) list_condense = 0 show_t_open_dates = True wiki_subpages = [] # Read optional check plan. check = [] if kwargs.has_key("check"): check = kwargs["check"].split(".") if name == "WikiTicketCalendar": if len(args) >= 5 or kwargs.has_key("cdate"): try: show_t_open_dates = kwargs["cdate"] in _TRUE_VALUES except KeyError: show_t_open_dates = args[4] in _TRUE_VALUES # TracQuery support for ticket selection query_args = "id!=0" if len(args) >= 7 or kwargs.has_key("query"): # prefer query arguments provided by kwargs try: query_args = kwargs["query"] except KeyError: query_args = args[6] provider = WikiCalendarTicketProvider(env) tickets = provider.harvest(req, query_args) # compress long ticket lists if len(args) >= 8 or kwargs.has_key("short"): # prefer query arguments provided by kwargs try: list_condense = int(kwargs["short"]) except KeyError: list_condense = int(args[7]) # control calendar display width cal_width = "100%;" if len(args) >= 9 or kwargs.has_key("width"): # prefer query arguments provided by kwargs try: cal_width = kwargs["width"] except KeyError: cal_width = args[8] # multiple wiki (sub)pages per day if kwargs.has_key("subpages"): wiki_subpages = kwargs["subpages"].split("|") # Prepare datetime objects for previous/next navigation link creation. prev_year = month_offset(today, -12) prev_quarter = month_offset(today, -3) prev_month = month_offset(today, -1) next_month = month_offset(today, 1) next_quarter = month_offset(today, 3) next_year = month_offset(today, 12) # Find first and last calendar day, probably in last/next month, # using datetime objects exactly at start-of-day here. # Note: Calendar days are numbered 0 (Mo) - 6 (Su). first_day_month = today.replace(day=1, second=0) first_day = first_day_month - timedelta(week_index(first_day_month, week_start)) last_day_month = next_month.replace(day=1) - timedelta(1) if ((last_day_month - first_day).days + 1) % 7 > 0: last_day = last_day_month + timedelta(7 - ((last_day_month - first_day).days + 1) % 7) else: last_day = last_day_month # Finally building the output now. # Begin with caption and optional navigation links. buff = tag.tr() if showbuttons is True: # Create calendar navigation buttons. nx = "next" pv = "prev" nav_pv_y = _nav_link(req, "<<", pv, prev_year, locale) nav_pv_q = _nav_link(req, " «", pv, prev_quarter, locale) nav_pv_m = _nav_link(req, " <", pv, prev_month, locale) nav_nx_m = _nav_link(req, "> ", nx, next_month, locale) nav_nx_q = _nav_link(req, "» ", nx, next_quarter, locale) nav_nx_y = _nav_link(req, ">>", nx, next_year, locale) # Add buttons for going to previous months and year. buff(nav_pv_y, nav_pv_q, nav_pv_m) # The caption will always be there. if has_babel: heading = tag.td(format_datetime(today, "MMMM y", locale=locale)) else: heading = tag.td(format_date(today, "%B %Y")) buff = buff(heading(class_="y")) if showbuttons is True: # Add buttons for going to next months and year. buff(nav_nx_m, nav_nx_q, nav_nx_y) buff = tag.caption(tag.table(tag.tbody(buff))) buff = tag.table(buff) if name == "WikiTicketCalendar": if cal_width.startswith("+") is True: width = ":".join(["min-width", cal_width]) buff(class_="wikitcalendar", style=width) else: buff(class_="wikitcalendar") if name == "WikiCalendar": buff(class_="wiki-calendar") heading = tag.tr() heading(align="center") if week_pref: # Add an empty cell matching the week number column below. heading(tag.th()) day_names = [(idx, day_name) for idx, day_name in get_day_names("abbreviated", "format", locale).iteritems()] # Read day names after shifting into correct position. for idx, name_ in day_names[week_start:7] + day_names[0:week_start]: col = tag.th(name_) if has_babel: weekend = idx >= locale.weekend_start and idx <= locale.weekend_end else: weekend = idx > 4 col(class_=("workday", "weekend")[weekend], scope="col") heading(col) heading = buff(tag.thead(heading)) # Building main calendar table body buff = tag.tbody() day = first_day while day.date() <= last_day.date(): # Insert a new row for every week. if (day - first_day).days % 7 == 0: line = tag.tr() line(align="right") if week_pref: cell = tag.td(week_num(env, day, week_start, week_num_start)) line(cell(class_="week")) if not (day < first_day_month or day > last_day_month): wiki = format_date(day, wiki_page_format) if day == today: a_class = "day today" td_class = "today" else: a_class = "day" td_class = "day" if uts: day_ts = to_utimestamp(day) day_ts_eod = day_ts + 86399999999 else: day_ts = to_timestamp(day) day_ts_eod = day_ts + 86399 # Check for milestone(s) on that day. db = env.get_db_cnx() cursor = db.cursor() cursor.execute( """ SELECT name FROM milestone WHERE due >= %s and due <= %s """, (day_ts, day_ts_eod), ) milestones = tag() for row in cursor: if not a_class.endswith("milestone"): a_class += " milestone" milestone = to_unicode(row[0]) url = env.href.milestone(milestone) milestone = "* " + milestone milestones = tag(milestones, tag.div(tag.a(milestone, href=url), class_="milestone")) label = tag.span(day.day) label(class_="day") # Generate wiki page links with name specified in # 'wiki_page_format', and check their existence. if len(wiki_subpages) > 0: pages = tag(label, Markup("<br />")) for page in wiki_subpages: label = tag(" ", page[0]) page = "/".join([wiki, page]) pages(self._wiki_link(req, args, kwargs, page, label, "subpage", check)) else: pages = self._wiki_link(req, args, kwargs, wiki, label, a_class, check) cell = tag.td(pages) cell(class_=td_class, valign="top") if name == "WikiCalendar": line(cell) else: if milestones: cell(milestones) else: cell(tag.br()) match = [] match_od = [] ticket_heap = tag("") ticket_list = tag.div("") ticket_list(align="left", class_="condense") # Get tickets with due date set to day. for t in tickets: due = t.get(self.tkt_due_field) if due is None or due in ("", "--"): continue else: if self.tkt_due_format == "ts": if not isinstance(due, datetime): continue if uts: due_ts = to_utimestamp(due) else: due_ts = to_timestamp(due) if due_ts < day_ts or due_ts > day_ts_eod: continue else: # Beware: Format might even be unicode string, # but str is required by the function. duedate = format_date(day, str(self.tkt_due_format)) if not due == duedate: continue tkt_id = t.get("id") ticket, short = _ticket_links(env, formatter, t) ticket_heap(ticket) if not tkt_id in match: if len(match) == 0: ticket_list(short) else: ticket_list(", ", short) match.append(tkt_id) # Optionally, get tickets created on day too. if show_t_open_dates is True: ticket_od_list = tag.div("") ticket_od_list(align="left", class_="opendate_condense") for t in tickets: if uts: ticket_ts = to_utimestamp(t.get("time")) else: ticket_ts = to_timestamp(t.get("time")) if ticket_ts < day_ts or ticket_ts > day_ts_eod: continue a_class = "opendate_" tkt_id = t.get("id") ticket, short = _ticket_links(env, formatter, t, a_class) ticket_heap(ticket) if not tkt_id in match: if len(match_od) == 0: ticket_od_list(short) else: ticket_od_list(", ", short) match_od.append(tkt_id) matches = len(match) + len(match_od) if list_condense > 0 and matches >= list_condense: if len(match_od) > 0: if len(match) > 0: ticket_list(", ") ticket_list = tag(ticket_list, ticket_od_list) line(cell(ticket_list)) else: line(cell(ticket_heap)) else: if name == "WikiCalendar": wiki = format_date(day, wiki_page_format) a_class = "day adjacent_month" pages = self._wiki_link(req, args, kwargs, wiki, day.day, a_class) cell = tag.td(pages, class_="day adjacent_month") line(cell) else: cell = tag.td("", class_="day adjacent_month") line(cell) # Append completed week rows. if (day - first_day).days % 7 == 6: buff(line) day += timedelta(1) buff = tag.div(heading(buff)) if name == "WikiTicketCalendar": if cal_width.startswith("+") is True: width = ":".join(["width", cal_width]) buff(class_="wikitcalendar", style=width) else: buff(class_="wikitcalendar") if name == "WikiCalendar": buff(class_="wiki-calendar") # Add common CSS stylesheet. if self.internal_css and not req.args.get("wikicalendar"): # Put definitions directly into the output. f = open("/".join([self.htdocs_path, "wikicalendar.css"]), "Ur") css = tag.style(Markup("<!--\n"), "\n".join(f.readlines()), Markup("-->\n"))(type="text/css") f.close() # Add hint to prevent multiple inclusions. req.args["wikicalendar"] = True return tag(css, buff) elif not req.args.get("wikicalendar"): add_stylesheet(req, "wikicalendar/wikicalendar.css") return buff
def get_sandwich_reminder_broadcast_type(language, day): return common_translate(language, SOLUTION_COMMON, u'order-sandwich-broadcast-day-broadcast-type', day=dates.get_day_names('wide', 'format', language)[SandwichSettings.DAYS.index(day)])
def __init__(self, master=None, **kw): """ Construct a Calendar with parent master. STANDARD OPTIONS cursor, font, borderwidth, state WIDGET-SPECIFIC OPTIONS year, month: initially displayed month, default is current month day: initially selected day, if month or year is given but not day, no initial selection, otherwise, default is today locale: locale to use, e.g. 'fr_FR' selectmode: "none" or "day" (default) define whether the user can change the selected day with a mouse click showweeknumbers: boolean (default is True) to show/hide week numbers textvariable: StringVar that will contain the currently selected date as str background: background color of calendar border and month/year name foreground: foreground color of month/year name bordercolor: day border color selectbackground: background color of selected day selectforeground: foreground color of selected day disabledselectbackground: background color of selected day in disabled state disabledselectforeground: foreground color of selected day in disabled state normalbackground: background color of normal week days normalforeground: foreground color of normal week days othermonthforeground: foreground color of normal week days belonging to the previous/next month othermonthbackground: background color of normal week days belonging to the previous/next month othermonthweforeground: foreground color of week-end days belonging to the previous/next month othermonthwebackground: background color of week-end days belonging to the previous/next month weekendbackground: background color of week-end days weekendforeground: foreground color of week-end days headersbackground: background color of day names and week numbers headersforeground: foreground color of day names and week numbers disableddaybackground: background color of days in disabled state disableddayforeground: foreground color of days in disabled state VIRTUAL EVENTS A <<CalendarSelected>> event is generated each time the user selects a day with the mouse. """ curs = kw.pop("cursor", "") font = kw.pop("font", "Liberation\ Sans 9") classname = kw.pop('class_', "Calendar") name = kw.pop('name', None) ttk.Frame.__init__(self, master, class_=classname, cursor=curs, name=name) self._style_prefixe = str(self) ttk.Frame.configure(self, style='main.%s.TFrame' % self._style_prefixe) self._textvariable = kw.pop("textvariable", None) self._font = Font(self, font) prop = self._font.actual() prop["size"] += 1 self._header_font = Font(self, **prop) # state state = kw.get('state', 'normal') try: bd = int(kw.pop('borderwidth', 2)) except ValueError: raise ValueError('expected integer for the borderwidth option.') self._cal = calendar.TextCalendar(calendar.MONDAY) # --- locale locale = kw.pop("locale", getdefaultlocale()[0]) self._day_names = get_day_names('abbreviated', locale=locale) self._month_names = get_month_names('wide', locale=locale) # --- date today = self.date.today() if (("month" in kw) or ("year" in kw)) and ("day" not in kw): month = kw.pop("month", today.month) year = kw.pop('year', today.year) self._sel_date = None # selected day else: day = kw.pop('day', today.day) month = kw.pop("month", today.month) year = kw.pop('year', today.year) try: self._sel_date = self.date(year, month, day) # selected day if self._textvariable is not None: self._textvariable.set(format_date(self._sel_date, 'short', locale)) except ValueError: self._sel_date = None self._date = self.date(year, month, 1) # (year, month) displayed by the calendar # --- selectmode selectmode = kw.pop("selectmode", "day") if selectmode not in ("none", "day"): raise ValueError("'selectmode' option should be 'none' or 'day'.") # --- show week numbers showweeknumbers = kw.pop('showweeknumbers', True) # --- style self.style = ttk.Style(self) active_bg = self.style.lookup('TEntry', 'selectbackground', ('focus',)) dis_active_bg = self.style.lookup('TEntry', 'selectbackground', ('disabled',)) dis_bg = self.style.lookup('TLabel', 'background', ('disabled',)) dis_fg = self.style.lookup('TLabel', 'foreground', ('disabled',)) # --- properties options = ['cursor', 'font', 'borderwidth', 'state', 'selectmode', 'textvariable', 'locale', 'showweeknumbers', 'selectbackground', 'selectforeground', 'disabledselectbackground', 'disabledselectforeground', 'normalbackground', 'normalforeground', 'background', 'foreground', 'bordercolor', 'othermonthforeground', 'othermonthbackground', 'othermonthweforeground', 'othermonthwebackground', 'weekendbackground', 'weekendforeground', 'headersbackground', 'headersforeground', 'disableddaybackground', 'disableddayforeground'] keys = list(kw.keys()) for option in keys: if option not in options: del(kw[option]) self._properties = {"cursor": curs, "font": font, "borderwidth": bd, "state": state, "locale": locale, "selectmode": selectmode, 'textvariable': self._textvariable, 'showweeknumbers': showweeknumbers, 'selectbackground': active_bg, 'selectforeground': 'white', 'disabledselectbackground': dis_active_bg, 'disabledselectforeground': 'white', 'normalbackground': 'white', 'normalforeground': 'black', 'background': 'gray30', 'foreground': 'white', 'bordercolor': 'gray70', 'othermonthforeground': 'gray45', 'othermonthbackground': 'gray93', 'othermonthweforeground': 'gray45', 'othermonthwebackground': 'gray75', 'weekendbackground': 'gray80', 'weekendforeground': 'gray30', 'headersbackground': 'gray70', 'headersforeground': 'black', 'disableddaybackground': dis_bg, 'disableddayforeground': dis_fg} self._properties.update(kw) # --- init calendar # --- *-- header: month - year header = ttk.Frame(self, style='main.%s.TFrame' % self._style_prefixe) f_month = ttk.Frame(header, style='main.%s.TFrame' % self._style_prefixe) self._l_month = ttk.Button(f_month, style='L.%s.TButton' % self._style_prefixe, command=self._prev_month) self._header_month = ttk.Label(f_month, width=10, anchor='center', style='main.%s.TLabel' % self._style_prefixe, font=self._header_font) self._r_month = ttk.Button(f_month, style='R.%s.TButton' % self._style_prefixe, command=self._next_month) self._l_month.pack(side='left', fill="y") self._header_month.pack(side='left', padx=4) self._r_month.pack(side='left', fill="y") f_year = ttk.Frame(header, style='main.%s.TFrame' % self._style_prefixe) self._l_year = ttk.Button(f_year, style='L.%s.TButton' % self._style_prefixe, command=self._prev_year) self._header_year = ttk.Label(f_year, width=4, anchor='center', style='main.%s.TLabel' % self._style_prefixe, font=self._header_font) self._r_year = ttk.Button(f_year, style='R.%s.TButton' % self._style_prefixe, command=self._next_year) self._l_year.pack(side='left', fill="y") self._header_year.pack(side='left', padx=4) self._r_year.pack(side='left', fill="y") f_month.pack(side='left', fill='x') f_year.pack(side='right') # --- *-- calendar self._cal_frame = ttk.Frame(self, style='cal.%s.TFrame' % self._style_prefixe) ttk.Label(self._cal_frame, style='headers.%s.TLabel' % self._style_prefixe).grid(row=0, column=0, sticky="eswn") for i in range(7): d = self._day_names[i] self._cal_frame.columnconfigure(i + 1, weight=1) ttk.Label(self._cal_frame, font=self._font, style='headers.%s.TLabel' % self._style_prefixe, anchor="center", text=d, width=4).grid(row=0, column=i + 1, sticky="ew", pady=(0, 1)) self._week_nbs = [] self._calendar = [] for i in range(1, 7): self._cal_frame.rowconfigure(i, weight=1) wlabel = ttk.Label(self._cal_frame, style='headers.%s.TLabel' % self._style_prefixe, font=self._font, padding=2, anchor="e", width=2) self._week_nbs.append(wlabel) wlabel.grid(row=i, column=0, sticky="esnw", padx=(0, 1)) if not showweeknumbers: wlabel.grid_remove() self._calendar.append([]) for j in range(1, 8): label = ttk.Label(self._cal_frame, style='normal.%s.TLabel' % self._style_prefixe, font=self._font, anchor="center") self._calendar[-1].append(label) label.grid(row=i, column=j, padx=(0, 1), pady=(0, 1), sticky="nsew") if selectmode is "day": label.bind("<1>", self._on_click) # --- *-- pack main elements header.pack(fill="x", padx=2, pady=2) self._cal_frame.pack(fill="both", expand=True, padx=bd, pady=bd) self.config(state=state) # --- bindings self.bind('<<ThemeChanged>>', self._setup_style) self._setup_style() self._display_calendar() if self._textvariable is not None: try: self._textvariable_trace_id = self._textvariable.trace_add('write', self._textvariable_trace) except AttributeError: self._textvariable_trace_id = self._textvariable.trace('w', self._textvariable_trace)
def by(self, by, values): if by == 'bysetpos': before = [-v for v in reversed(values) if v < 0] after = [v for v in values if v > 0] parts = [] t = 0 if after: if len(after) == 1: parts.append('la %s' % self.nth(after[0], self.FEMININ)) t += 1 else: t += 2 parts.append( 'les %s premières' % self.join_list([self.nth(val) for val in after])) if before: if len(before) == 1: if before[0] == 1: parts.append('la dernière') else: parts.append('l’%sdernière' % ('avant-' * (before[0] - 1))) t += 1 else: t += 2 parts.append( 'les %s dernières' % self.join_list([self.nth(val) for val in before])) return ' et '.join(parts) + ' occurence%s' % ('s' if t != 1 else '') if by == 'bymonth': return 'en %s' % self.join_list([ get_month_names(locale=self.__class__.__name__)[month] for month in values ]) if by == 'bymonthday': if len(values) == 1: return 'le %s jour du mois' % self.nth(val) return 'les %s jours du mois' % self.join_list( [self.nth(val) for val in values]) if by == 'byyearday': if len(values) == 1: return 'le %s jour de l’année' % self.nth(val) return 'les %s jours de l’année' % self.join_list( [self.nth(val) for val in values]) if by == 'byweekno': if len(values) == 1: return 'la semaine n°%d' % values[0] return 'les semaines n°%s' % self.join_list(values) if by == 'byweekday': dow = get_day_names(locale=self.__class__.__name__) return 'le %s' % self.join_list([dow[val] for val in values]) if by == 'byeaster': before = [-v for v in reversed(values) if v < 0] after = [v for v in values if v > 0] parts = [] if before: if len(before) == 1 and before[0] == 1: parts.append('la veille de Pâques') else: parts.append('%s jours avant Pâques' % self.join_list(before)) if after: if len(after) == 1 and after[0] == 1: parts.append('le lendemain de Pâques') else: parts.append('%s jours après Pâques' % self.join_list(after)) return ' et '.join(parts)
def by(self, by, values): if by == 'bysetpos': before = [-v for v in reversed(values) if v < 0] after = [v for v in values if v > 0] parts = [] t = 0 if after: if len(after) == 1 and after[0] == 1: parts.append('the first') t += 1 else: parts.append( 'the %s first' % self.join_list([self.nth(val) for val in after])) t += 2 if before: if len(before) == 1 and before[0] == 1: parts.append('the last') t += 1 else: parts.append( 'the %s last' % self.join_list([self.nth(val) for val in before])) t += 2 return ' and '.join(parts) + ' occurence%s' % ('s' if t != 1 else '') if by == 'bymonth': return 'on %s' % self.join_list([ get_month_names(locale=self.__class__.__name__)[month] for month in values ]) if by == 'bymonthday': return 'the %s of month' % self.join_list(values) if by == 'byyearday': return 'the %s of year' % self.join_list(values) if by == 'byweekno': return 'the week%s n°%s' % ('s' if len(values) > 1 else '', self.join_list(values)) if by == 'byweekday': dow = get_day_names(locale=self.__class__.__name__) return 'on %s' % self.join_list([dow[val] for val in values]) if by == 'byeaster': before = [-v for v in reversed(values) if v < 0] after = [v for v in values if v > 0] parts = [] if before: if len(before) == 1 and before[0] == 1: parts.append('1 day before Easter') else: parts.append('%s days before Easter' % self.join_list(before)) if after: if len(after) == 1 and before[0] == 1: parts.append('1 day after Easter') else: parts.append('%s days after Easter' % self.join_list(after)) return ' and '.join(parts)
def day_str(self, language): return dates.get_day_names('wide', locale=language)[self.day].capitalize()
def get_weekday_names(locale=LC_TIME): """Get list of full weekday names.""" return get_day_names(width='wide', locale=locale)
def get_abbr_weekday_names(locale=LC_TIME): """Get list of abbreviated weekday names.""" try: return get_day_names(width='abbreviated', locale=locale) except babel.UnknownLocaleError: return []
def gen_calendar(self, tickets, query, month, width=None, nav=True): milestones = self._get_milestones() req = self.req locale = self._get_locale() first_week_day = self._get_first_week_day(locale) start_date_format = self.mod.start_date_format due_date_format = self.mod.due_date_format if not month: month = datetime.now(req.tz) month = datetime(month.year, month.month, 1).date() # init data today = datetime.now(req.tz).date() # generate calendar data weeks = self._get_month_calendar(month.year, month.month, first_week_day, locale) days = sorted(sum(weeks, [])) tickets = self._filter_tickets(days, tickets, req.tz) milestones = self._filter_milestones(days, milestones, req.tz) cal = [[{ 'date': day, 'tickets': tickets[day], 'milestones': milestones[day] } for day in week] for week in weeks] def genli(t): if isinstance(t, Milestone): return self._create_milestone_item(t) else: return self._create_ticket_item(t) def gentd(week_idx, day_info): day = day_info['date'] tt = day_info['milestones'] + day_info['tickets'] if len(tt) < 6: ttshow = tt ttall = [] else: ttshow = tt[:4] ttall = tt tdclass = [] if day == today: tdclass.append('today') if day.weekday() in (5, 6): tdclass.append('weekend') formatted_day = format_date(day, format='long', locale=locale) td = tag.td(class_=' '.join(tdclass), data_for_start_date=day.strftime(start_date_format), data_for_due_date=day.strftime(due_date_format), data_fdate=formatted_day) label = [] if day == today: label.append(tag.span(_("Today"), class_='today')) label.append( tag.span(unicode(day.day), class_=('day normal', 'day')[day == today])) td(tag.div(label)) if ttshow: td(tag.ul([genli(t) for t in ttshow])) if ttall: id = 'calendar-more-%s' % str(day) td( tag.a(_("%d more tickets...") % (len(ttall) - 4), href='#' + id, class_='show-all-list'), tag.div(tag.h4(formatted_day), tag.ul([genli(t) for t in ttall]), class_='ticketcalendar-popup-list', id=id, data_title=format_date(day, locale=locale, format='full'))) return td day_names = get_day_names(locale=locale, width='abbreviated') day_names = [ day_names[(idx + first_week_day) % 7] for idx in xrange(7) ] header = tag.div(class_='ticketcalendar-header') if nav: def nav_href(d): return self.get_box_href(query, d) def nav_pager(d): return tag.span(tag.a(u'\u25c4', href=nav_href(d - timedelta(days=1))), tag.a(_("Current month"), href=nav_href(date.today())), tag.a(u'\u25ba', href=nav_href(d + timedelta(days=31))), class_='ticketcalendar-pager') def nav_macro(): macro = ( '[[TicketCalendar(type=box,month=%(month)s,' 'query=%(query)s,order=%(order)s%(extra)s)]]' % (dict(month=month.strftime('%Y-%m'), query=self.build_query_string(query.constraints), order=query.order, extra=query.desc and ',desc=1' or ''))) text = tag.input(type='text', readonly='readonly', size='80', value=macro, style='width:0;display:none') return tag.span(_("Macro"), text, class_='ticketcalendar-macro') header( tag.div(nav_macro(), nav_pager(month), class_='ticketcalendar-nav')) header( tag.h4( _("%(month_name)s, %(year)s", month_name=_get_month_name(month, locale), year=month.year))) calendar = tag.table( tag.thead(tag.tr(tag.th(name) for name in day_names)), tag.tbody([ tag.tr([gentd(idx, d) for d in w]) for idx, w in enumerate(cal) ]), class_='calendar') can_create = 'TICKET_CREATE' in req.perm ticket_box = tag.div( tag.h4(tag.span('', class_='tc-today-date')), tag.ul( tag.li( tag.a(tag_( "New ticket with \"%(date)s\" as the start date", date=tag.span('', data='start-date')), data_href=req.href('newticket', [(self.mod.start_date_name, '')]), class_='newticket-start-date')), tag.li( tag.a(tag_("New ticket with \"%(date)s\" as the due date", date=tag.span('', data='due-date')), data_href=req.href('newticket', [(self.mod.due_date_name, '')]), class_='newticket-due-date'))), title=_("Create new ticket"), class_='ticketcalendar-newticket-box', style='display:none', data_writable=(None, 'writable')[can_create]) class_ = ('ticketcalendar', 'ticketcalendar ticketcalendar-can-create')[can_create] return tag.div(header, calendar, ticket_box, class_=class_, style=width and ('width: %s' % width) or None)
def expand_macro(self, formatter, name, arguments): """Returns macro content.""" env = self.env req = formatter.req tz = req.tz # Parse arguments from macro invocation. args, kwargs = parse_args(arguments, strict=False) # Enable week number display regardless of argument position. week_pref = 'w' in args and args.pop(args.index('w')) week_pref = week_pref and week_pref or kwargs.get('w') week_start = None week_num_start = None # Parse per-instance week calculation rules, if available. if week_pref: if ':' not in week_pref: # Treat undelimitted setting as week start. week_pref += ':' w_start, wn_start = week_pref.split(':') try: week_start = int(w_start) except ValueError: week_start = None else: week_start = week_start > -1 and week_start < 7 and \ week_start or None try: week_num_start = int(wn_start) except ValueError: week_num_start = None else: week_num_start = week_num_start in (1, 4, 7) and \ week_num_start or None # Respect user's locale, if available. try: locale = Locale.parse(str(req.locale)) except (AttributeError, UnknownLocaleError): # Attribute 'req.locale' vailable since Trac 0.12. locale = None if has_babel: if locale: if not locale.territory: # Search first locale, which has the same `language` and # territory in preferred languages. for l in req.languages: l = l.replace('-', '_').lower() if l.startswith(locale.language.lower() + '_'): try: l = Locale.parse(l) if l.territory: locale = l break # first one rules except UnknownLocaleError: pass if not locale.territory and locale.language in LOCALE_ALIASES: locale = Locale.parse(LOCALE_ALIASES[locale.language]) else: # Default fallback. locale = Locale('en', 'US') env.log.debug('Locale setting for wiki calendar: %s' % locale.get_display_name('en')) if not week_start: if week_pref and week_pref.lower().startswith('iso'): week_start = 0 week_num_start = 4 elif has_babel: week_start = locale.first_week_day else: import calendar week_start = calendar.firstweekday() # ISO calendar will remain as default. if not week_num_start: if week_start == 6: week_num_start = 1 else: week_num_start = 4 env.log.debug('Effective settings: first_week_day=%s, ' '1st_week_of_year_rule=%s' % (week_start, week_num_start)) # Find year and month of interest. year = req.args.get('year') # Not clicked on any previous/next button, next look for macro args. if not year and len(args) >= 1 and args[0] != "*": year = args[0] year = year and year.isnumeric() and int(year) or None month = req.args.get('month') # Not clicked on any previous/next button, next look for macro args. if not month and len(args) >= 2 and args[1] != "*": month = args[1] month = month and month.isnumeric() and int(month) or None now = datetime.now(tz) # Force offset from start-of-day to avoid a false 'today' marker, # but use it only on request of different month/year. now.replace(second=1) today = None if (month and month != now.month) or (year and year != now.year): today = now.replace(year=year, month=month, day=1) # Use current month and year, if nothing else has been requested. if not today: today = now.replace(hour=0, minute=0, second=0, microsecond=0) showbuttons = True if len(args) >= 3 or kwargs.has_key('nav'): try: showbuttons = kwargs['nav'] in _TRUE_VALUES except KeyError: showbuttons = args[2] in _TRUE_VALUES wiki_page_format = "%Y-%m-%d" if len(args) >= 4 and args[3] != "*" or kwargs.has_key('wiki'): try: wiki_page_format = str(kwargs['wiki']) except KeyError: wiki_page_format = str(args[3]) # Support relative paths in macro arguments for wiki page links. wiki_page_format = resolve_relative_name(wiki_page_format, formatter.resource.id) list_condense = 0 show_t_open_dates = True wiki_subpages = [] # Read optional check plan. check = [] if kwargs.has_key('check'): check = kwargs['check'].split('.') if name == 'WikiTicketCalendar': if len(args) >= 5 or kwargs.has_key('cdate'): try: show_t_open_dates = kwargs['cdate'] in _TRUE_VALUES except KeyError: show_t_open_dates = args[4] in _TRUE_VALUES # TracQuery support for ticket selection query_args = "id!=0" if len(args) >= 7 or kwargs.has_key('query'): # prefer query arguments provided by kwargs try: query_args = kwargs['query'] except KeyError: query_args = args[6] # compress long ticket lists if len(args) >= 8 or kwargs.has_key('short'): # prefer query arguments provided by kwargs try: list_condense = int(kwargs['short']) except KeyError: list_condense = int(args[7]) # control calendar display width cal_width = "100%;" if len(args) >= 9 or kwargs.has_key('width'): # prefer query arguments provided by kwargs try: cal_width = kwargs['width'] except KeyError: cal_width = args[8] # multiple wiki (sub)pages per day if kwargs.has_key('subpages'): wiki_subpages = kwargs['subpages'].split('|') # Prepare datetime objects for previous/next navigation link creation. prev_year = month_offset(today, -12) prev_quarter = month_offset(today, -3) prev_month = month_offset(today, -1) next_month = month_offset(today, 1) next_quarter = month_offset(today, 3) next_year = month_offset(today, 12) # Find first and last calendar day, probably in last/next month, # using datetime objects exactly at start-of-day here. # Note: Calendar days are numbered 0 (Mo) - 6 (Su). first_day_month = today.replace(day=1, second=0) first_day = first_day_month - timedelta( week_index(first_day_month, week_start)) last_day_month = next_month.replace(day=1) - timedelta(1) if ((last_day_month - first_day).days + 1) % 7 > 0: last_day = last_day_month + timedelta(7 - ( (last_day_month - first_day).days + 1) % 7) else: last_day = last_day_month # Find relevant tickets. if name == 'WikiTicketCalendar': daystr = (uts and '..' or ':').join([ format_datetime(first_day, locale=locale), format_datetime(last_day, locale=locale) ]) provider = WikiCalendarTicketProvider(env) query_args = query_args and query_args + '&' or '' tkt_due = provider.harvest( req, query_args + '='.join([self.tkt_due_field, daystr])) if show_t_open_dates: tkt_new = provider.harvest( req, query_args + '='.join(['created', daystr])) # Finally building the output now. # Begin with caption and optional navigation links. buff = tag.tr() if showbuttons is True: # Create calendar navigation buttons. nx = 'next' pv = 'prev' nav_pv_y = _nav_link(req, '<<', pv, prev_year, locale) nav_pv_q = _nav_link(req, ' «', pv, prev_quarter, locale) nav_pv_m = _nav_link(req, ' <', pv, prev_month, locale) nav_nx_m = _nav_link(req, '> ', nx, next_month, locale) nav_nx_q = _nav_link(req, '» ', nx, next_quarter, locale) nav_nx_y = _nav_link(req, '>>', nx, next_year, locale) # Add buttons for going to previous months and year. buff(nav_pv_y, nav_pv_q, nav_pv_m) # The caption will always be there. if has_babel: heading = tag.td(format_datetime(today, 'MMMM y', locale=locale)) else: heading = tag.td(format_date(today, '%B %Y')) buff = buff(heading(class_='y')) if showbuttons is True: # Add buttons for going to next months and year. buff(nav_nx_m, nav_nx_q, nav_nx_y) buff = tag.caption(tag.table(tag.tbody(buff))) buff = tag.table(buff) if name == 'WikiTicketCalendar': if cal_width.startswith('+') is True: width = ":".join(['min-width', cal_width]) buff(class_='wikitcalendar', style=width) else: buff(class_='wikitcalendar') if name == 'WikiCalendar': buff(class_='wiki-calendar') heading = tag.tr() heading(align='center') if week_pref: # Add an empty cell matching the week number column below. heading(tag.th()) day_names = [(idx, day_name) for idx, day_name in get_day_names( 'abbreviated', 'format', locale).iteritems()] # Read day names after shifting into correct position. for idx, name_ in day_names[week_start:7] + day_names[0:week_start]: col = tag.th(name_) if has_babel: weekend = idx >= locale.weekend_start and \ idx <= locale.weekend_end else: weekend = idx > 4 col(class_=('workday', 'weekend')[weekend], scope='col') heading(col) heading = buff(tag.thead(heading)) # Building main calendar table body buff = tag.tbody() day = first_day while day.date() <= last_day.date(): # Insert a new row for every week. if (day - first_day).days % 7 == 0: line = tag.tr() line(align='right') if week_pref: cell = tag.td( week_num(env, day, week_start, week_num_start)) line(cell(class_='week')) if not (day < first_day_month or day > last_day_month): wiki = format_date(day, wiki_page_format) if day == today: a_class = 'day today' td_class = 'today' else: a_class = 'day' td_class = 'day' if uts: day_ts = to_utimestamp(day) day_ts_eod = day_ts + 86399999999 else: day_ts = to_timestamp(day) day_ts_eod = day_ts + 86399 # Check for milestone(s) on that day. #db = env.get_read_db() #cursor = db.cursor() #cursor.execute(""" # SELECT name # FROM milestone # WHERE due >= %s and due <= %s #""", (day_ts, day_ts_eod)) cursor = self.env.db_query( """ SELECT name FROM milestone WHERE due >= %s and due <= %s """, (day_ts, day_ts_eod)) milestones = tag() for row in cursor: if not a_class.endswith('milestone'): a_class += ' milestone' milestone = to_unicode(row[0]) url = env.href.milestone(milestone) milestone = '* ' + milestone milestones = tag( milestones, tag.div(tag.a(milestone, href=url), class_='milestone')) label = tag.span(day.day) label(class_='day') # Generate wiki page links with name specified in # 'wiki_page_format', and check their existence. if len(wiki_subpages) > 0: pages = tag(label, Markup('<br />')) for page in wiki_subpages: label = tag(' ', page[0]) page = '/'.join([wiki, page]) pages( self._wiki_link(req, args, kwargs, page, label, 'subpage', check)) else: pages = self._wiki_link(req, args, kwargs, wiki, label, a_class, check) cell = tag.td(pages) cell(class_=td_class, valign='top') if name == 'WikiCalendar': line(cell) else: if milestones: cell(milestones) else: cell(tag.br()) match = [] match_od = [] ticket_heap = tag('') ticket_list = tag.div('') ticket_list(align='left', class_='condense') # Get tickets with due date set to day. for t in tkt_due: due = t.get(self.tkt_due_field) if due is None or due in ('', '--'): continue else: if self.tkt_due_format == 'ts': if not isinstance(due, datetime): continue if uts: due_ts = to_utimestamp(due) else: due_ts = to_timestamp(due) if due_ts < day_ts or due_ts > day_ts_eod: continue else: # Beware: Format might even be unicode string, # but str is required by the function. duedate = format_date(day, str(self.tkt_due_format)) if not due == duedate: continue tkt_id = t.get('id') ticket, short = _ticket_links(env, formatter, t) ticket_heap(ticket) if not tkt_id in match: if len(match) == 0: ticket_list(short) else: ticket_list(', ', short) match.append(tkt_id) # Optionally, get tickets created on day too. if show_t_open_dates: ticket_od_list = tag.div('') ticket_od_list(align='left', class_='opendate_condense') for t in tkt_new: if uts: ticket_ts = to_utimestamp(t.get('time')) else: ticket_ts = to_timestamp(t.get('time')) if ticket_ts < day_ts or ticket_ts > day_ts_eod: continue a_class = 'opendate_' tkt_id = t.get('id') ticket, short = _ticket_links( env, formatter, t, a_class) ticket_heap(ticket) if not tkt_id in match: if len(match_od) == 0: ticket_od_list(short) else: ticket_od_list(', ', short) match_od.append(tkt_id) matches = len(match) + len(match_od) if list_condense > 0 and matches >= list_condense: if len(match_od) > 0: if len(match) > 0: ticket_list(', ') ticket_list = tag(ticket_list, ticket_od_list) line(cell(ticket_list)) else: line(cell(ticket_heap)) else: if name == 'WikiCalendar': wiki = format_date(day, wiki_page_format) a_class = 'day adjacent_month' pages = self._wiki_link(req, args, kwargs, wiki, day.day, a_class) cell = tag.td(pages, class_='day adjacent_month') line(cell) else: cell = tag.td('', class_='day adjacent_month') line(cell) # Append completed week rows. if (day - first_day).days % 7 == 6: buff(line) day += timedelta(1) buff = tag.div(heading(buff)) if name == 'WikiTicketCalendar': if cal_width.startswith('+') is True: width = ":".join(['width', cal_width]) buff(class_='wikitcalendar', style=width) else: buff(class_='wikitcalendar') if name == 'WikiCalendar': buff(class_='wiki-calendar') # Add common CSS stylesheet. if self.internal_css and not req.args.get('wikicalendar'): # Put definitions directly into the output. f = open('/'.join([self.htdocs_path, 'wikicalendar.css']), 'Ur') css = tag.style(Markup('<!--\n'), '\n'.join(f.readlines()), Markup('-->\n'))(type="text/css") f.close() # Add hint to prevent multiple inclusions. req.args['wikicalendar'] = True return tag(css, buff) elif not req.args.get('wikicalendar'): add_stylesheet(req, 'wikicalendar/wikicalendar.css') return buff
def __init__(self, master, event, new=False): Toplevel.__init__(self, master) self.minsize(410, 402) if master.winfo_ismapped(): self.transient(master) self.protocol('WM_DELETE_WINDOW', self.cancel) self._only_nb = self.register(only_nb) self.event = event if new: self.title(_('New Event')) else: self.title(_('Edit Event')) self._new = new self._task = BooleanVar(self, bool(event['Task'])) self._whole_day = BooleanVar(self, event['WholeDay']) # --- style style = Style(self) active_bg = style.lookup('TEntry', 'selectbackground', ('focus', )) self.alarms = [] notebook = Notebook(self) notebook.pack(fill='both', expand=True) Button(self, text=_('Ok'), command=self.ok).pack(pady=(10, 6), padx=4) # --- event settings frame_event = Frame(notebook) notebook.add(frame_event, text=_('Event'), sticky='eswn', padding=4) frame_event.columnconfigure(1, weight=1) frame_event.rowconfigure(5, weight=1) self.img_moins = PhotoImage(master=self, file=IM_DEL) self.img_bell = PhotoImage(master=self, file=IM_BELL) Label(frame_event, text=_('Summary')).grid(row=0, column=0, padx=4, pady=6, sticky='e') Label(frame_event, text=_('Place')).grid(row=1, column=0, padx=4, pady=6, sticky='e') Label(frame_event, text=_('Start')).grid(row=2, column=0, padx=4, pady=6, sticky='e') self._end_label = Label(frame_event, text=_('End')) self._end_label.grid(row=3, column=0, padx=4, pady=6, sticky='e') frame_task = Frame(frame_event) frame_task.grid(row=4, column=1, padx=4, pady=6, sticky='w') Label(frame_event, text=_('Description')).grid(row=5, column=0, padx=4, pady=6, sticky='e') Label(frame_event, text=_('Category')).grid(row=6, column=0, padx=4, pady=6, sticky='e') Button(frame_event, image=self.img_bell, command=self.add_reminder, padding=0).grid(row=7, column=0, padx=4, pady=6, sticky='en') self.summary = Entry(frame_event, width=35) self.summary.insert(0, self.event['Summary']) self.summary.grid(row=0, column=1, padx=4, pady=6, sticky='ew') self.place = Entry(frame_event, width=35) self.place.insert(0, self.event['Place']) self.place.grid(row=1, column=1, padx=4, pady=6, sticky='ew') frame_start = Frame(frame_event) frame_start.grid(row=2, column=1, padx=4, pady=6, sticky='w') frame_end = Frame(frame_event) frame_end.grid(row=3, column=1, padx=4, pady=6, sticky='w') txt_frame = Frame(frame_event, style='txt.TFrame', border=1, relief='sunken') self.desc = Text(txt_frame, width=35, height=4, highlightthickness=0, relief='flat', selectbackground=active_bg) self.desc.insert('1.0', self.event['Description']) self.desc.pack(fill='both', expand=True) txt_frame.grid(row=5, column=1, padx=4, pady=6, sticky='ewsn') cats = list(CONFIG.options('Categories')) width = max([len(cat) for cat in cats]) self.category = Combobox(frame_event, width=width + 2, values=cats, state='readonly') self.category.set(event['Category']) self.category.grid(row=6, column=1, padx=4, pady=6, sticky='w') self.frame_alarms = Frame(frame_event) self.frame_alarms.grid(row=7, column=1, sticky='w') # --- *--- task Checkbutton(frame_task, text=_('Task'), command=self._change_label, variable=self._task).pack(side='left') self.task_progress = Combobox(frame_task, state='readonly', width=9, values=(_('Pending'), _('In Progress'), _('Completed'), _('Cancelled'))) self.task_progress.pack(side='left', padx=(8, 4)) self.in_progress = Combobox( frame_task, state='readonly', width=5, values=['{}%'.format(i) for i in range(0, 110, 10)]) self.in_progress.pack(side='left', padx=4) if not event['Task']: self.task_progress.set(_('Pending')) self.in_progress.set('0%') elif '%' in event['Task']: self.task_progress.set(_('In Progress')) self.in_progress.set(event['Task']) else: self.task_progress.set(_(event['Task'])) self.in_progress.set('0%') # calendar settings prop = { op: CONFIG.get('Calendar', op) for op in CONFIG.options('Calendar') } prop['font'] = "Liberation\ Sans 9" prop.update(selectforeground='white', selectbackground=active_bg) locale = CONFIG.get('General', 'locale') # --- *--- start date self.start_date = self.event['Start'] self.start_entry = DateEntry(frame_start, locale=locale, width=10, justify='center', year=self.start_date.year, month=self.start_date.month, day=self.start_date.day, **prop) self.start_hour = Combobox(frame_start, width=3, justify='center', state='readonly', exportselection=False, values=['%02d' % i for i in range(24)]) self.start_hour.set('%02d' % self.start_date.hour) self.start_min = Combobox(frame_start, width=3, justify='center', state='readonly', exportselection=False, values=['%02d' % i for i in range(0, 60, 5)]) self.start_min.set('%02d' % self.start_date.minute) self.start_entry.pack(side='left', padx=(0, 18)) self.start_hour.pack(side='left', padx=(4, 0)) self.start_date = self.start_date.date() Label(frame_start, text=':').pack(side='left') self.start_min.pack(side='left', padx=(0, 4)) Checkbutton(frame_start, text=_("whole day"), variable=self._whole_day, command=self._toggle_whole_day).pack(side='left', padx=4) # --- *--- end date self.end_date = self.event['End'] self.end_entry = DateEntry(frame_end, justify='center', locale=locale, width=10, year=self.end_date.year, month=self.end_date.month, day=self.end_date.day, **prop) self.end_hour = Combobox(frame_end, width=3, justify='center', state='readonly', exportselection=False, values=['%02d' % i for i in range(24)]) self.end_hour.set('%02d' % self.end_date.hour) self.end_min = Combobox(frame_end, width=3, justify='center', state='readonly', exportselection=False, values=['%02d' % i for i in range(0, 60, 5)]) self.end_min.set('%02d' % self.end_date.minute) self.end_entry.pack(side='left', padx=(0, 18)) self.end_hour.pack(side='left', padx=(4, 0)) Label(frame_end, text=':').pack(side='left') self.end_min.pack(side='left', padx=(0, 4)) self.end_date = self.end_date.date() for date in self.event['Reminders'].values(): self.add_reminder(date) self._toggle_whole_day() # --- repetition settings frame_rep = Frame(notebook) notebook.add(frame_rep, text=_('Repetition'), padding=4, sticky='eswn') frame_rep.columnconfigure(0, weight=1) frame_rep.columnconfigure(1, weight=1) frame_rep.rowconfigure(1, weight=1) self._repeat = BooleanVar(self, bool(self.event['Repeat'])) repeat = { 'Frequency': 'year', 'Limit': 'always', 'NbTimes': 1, 'EndDate': (datetime.now() + timedelta(days=1)).date(), 'WeekDays': [self.start_date.isocalendar()[2] - 1] } repeat.update(self.event['Repeat']) self._repeat_freq = StringVar(self, repeat['Frequency']) Checkbutton(frame_rep, text=_('Repeat event'), variable=self._repeat, command=self._toggle_rep).grid(row=0, column=0, columnspan=2, padx=4, pady=6, sticky='w') # --- *--- Frequency frame_freq = LabelFrame(frame_rep, text=_('Frequency')) frame_freq.grid(row=1, column=0, sticky='eswn', padx=(0, 3)) self._lfreq = Label(frame_freq, text=_('Every:')) self._lfreq.grid(row=0, column=0, padx=4, pady=2, sticky='e') self._freqs = [] for i, val in enumerate(['Year', 'Month', 'Week']): r = Radiobutton(frame_freq, text=_(val), variable=self._repeat_freq, value=val.lower(), command=self._toggle_wd) r.grid(row=i, column=1, padx=4, pady=2, sticky='nw') self._freqs.append(r) frame_days = Frame(frame_freq) frame_days.grid(row=2, column=2, padx=4, pady=2, sticky='nw') self._week_days = [] days = get_day_names("wide", locale=locale) days = [days[i] for i in range(7)] for day in days: ch = Checkbutton(frame_days, text=day) ch.pack(anchor='w') self._week_days.append(ch) for d in repeat['WeekDays']: self._week_days[int(d)].state(('selected', )) # --- *--- Limit frame_lim = LabelFrame(frame_rep, text=_('Limit')) frame_lim.grid(row=1, column=1, sticky='eswn', padx=(3, 0)) frame_lim.grid(row=1, column=1, sticky='eswn', padx=(3, 0)) self._repeat_lim = StringVar(self, repeat['Limit']) # always r1 = Radiobutton(frame_lim, text=_('Always'), value='always', variable=self._repeat_lim, command=self._toggle_lim) r1.grid(row=0, column=0, sticky='w') # until r2 = Radiobutton(frame_lim, text=_('Until'), value='until', variable=self._repeat_lim, command=self._toggle_lim) r2.grid(row=1, column=0, sticky='w') until_date = repeat['EndDate'] self.until_entry = DateEntry(frame_lim, width=10, justify='center', locale=locale, year=until_date.year, month=until_date.month, day=until_date.day, **prop) self.until_entry.grid(row=1, column=1, columnspan=2, sticky='w', padx=(4, 10), pady=2) # after r3 = Radiobutton(frame_lim, text=_('After'), value='after', variable=self._repeat_lim, command=self._toggle_lim) r3.grid(row=2, column=0, sticky='w') frame_after = Frame(frame_lim, style='txt.TFrame', relief='sunken', border=1) self.s_after = Spinbox(frame_after, from_=0, to=100, width=3, justify='center', relief='flat', highlightthickness=0, validate='key', validatecommand=(self._only_nb, '%P'), disabledbackground='white') self.s_after.pack() self.s_after.delete(0, 'end') self.s_after.insert(0, str(repeat['NbTimes'])) frame_after.grid(row=2, column=1, padx=4, pady=2, sticky='w') self._llim = Label(frame_lim, text=_('times')) self._llim.grid(row=2, column=2, padx=0, pady=2, sticky='w') self._rb_lim = [r1, r2, r3] self._toggle_rep() self._change_label() # --- bindings self.bind('<Configure>') self.task_progress.bind('<<ComboboxSelected>>', self._toggle_in_progress) self.start_entry.bind('<<DateEntrySelected>>', self._select_start) self.end_entry.bind('<<DateEntrySelected>>', self._select_end) self.start_hour.bind("<<ComboboxSelected>>", self._select_start_hour) self.start_min.bind("<<ComboboxSelected>>", self._select_start_min) self.end_min.bind("<<ComboboxSelected>>", self._select_end_time) self.end_hour.bind("<<ComboboxSelected>>", self._select_end_time) self.bind_class("TCombobox", "<<ComboboxSelected>>", self.__clear_selection, add=True) # self.wait_visibility(self) # self.grab_set() self.summary.focus_set()
def gen_calendar(self, tickets, query, month, width=None, nav=True): milestones = self._get_milestones() req = self.req locale = self._get_locale() first_week_day = self._get_first_week_day(locale) start_date_format = self.mod.start_date_format due_date_format = self.mod.due_date_format if not month: month = datetime.now(req.tz) month = datetime(month.year, month.month, 1).date() # init data today = datetime.now(req.tz).date() # generate calendar data weeks = self._get_month_calendar(month.year, month.month, first_week_day, locale) days = sorted(sum(weeks, [])) tickets = self._filter_tickets(days, tickets, req.tz) milestones = self._filter_milestones(days, milestones, req.tz) cal = [[{'date': day, 'tickets': tickets[day], 'milestones': milestones[day]} for day in week] for week in weeks] def genli(t): if isinstance(t, Milestone): return self._create_milestone_item(t) else: return self._create_ticket_item(t) def gentd(week_idx, day_info): day = day_info['date'] tt = day_info['milestones'] + day_info['tickets'] if len(tt) < 6: ttshow = tt ttall = [] else: ttshow = tt[:4] ttall = tt tdclass = [] if day == today: tdclass.append('today') if day.weekday() in (5, 6): tdclass.append('weekend') formatted_day = format_date(day, format='long', locale=locale) td = tag.td( class_=' '.join(tdclass), data_for_start_date=day.strftime(start_date_format), data_for_due_date=day.strftime(due_date_format), data_fdate=formatted_day) label = [] if day == today: label.append(tag.span(_("Today"), class_='today')) label.append(tag.span(unicode(day.day), class_=('day normal', 'day')[day == today])) td(tag.div(label)) if ttshow: td(tag.ul([genli(t) for t in ttshow])) if ttall: id = 'calendar-more-%s' % str(day) td(tag.a(_("%d more tickets...") % (len(ttall) - 4), href='#' + id, class_='show-all-list'), tag.div(tag.h4(formatted_day), tag.ul([genli(t) for t in ttall]), class_='ticketcalendar-popup-list', id=id, data_title=format_date(day, locale=locale, format='full'))) return td day_names = get_day_names(locale=locale, width='abbreviated') day_names = [day_names[(idx + first_week_day) % 7] for idx in xrange(7)] header = tag.div(class_='ticketcalendar-header') if nav: def nav_href(d): return self.get_box_href(query, d) def nav_pager(d): return tag.span( tag.a(u'\u25c4', href=nav_href(d - timedelta(days=1))), tag.a(_("Current month"), href=nav_href(date.today())), tag.a(u'\u25ba', href=nav_href(d + timedelta(days=31))), class_='ticketcalendar-pager') def nav_macro(): macro = ( '[[TicketCalendar(type=box,month=%(month)s,' 'query=%(query)s,order=%(order)s%(extra)s)]]' % (dict(month=month.strftime('%Y-%m'), query=self.build_query_string(query.constraints), order=query.order, extra=query.desc and ',desc=1' or ''))) text = tag.input(type='text', readonly='readonly', size='80', value=macro, style='width:0;display:none') return tag.span(_("Macro"), text, class_='ticketcalendar-macro') header(tag.div(nav_macro(), nav_pager(month), class_='ticketcalendar-nav')) header(tag.h4(_("%(month_name)s, %(year)s", month_name=_get_month_name(month, locale), year=month.year))) calendar = tag.table( tag.thead(tag.tr(tag.th(name) for name in day_names)), tag.tbody([tag.tr([gentd(idx, d) for d in w]) for idx, w in enumerate(cal)]), class_='calendar') can_create = 'TICKET_CREATE' in req.perm ticket_box = tag.div( tag.h4(tag.span('', class_='tc-today-date')), tag.ul( tag.li(tag.a( tag_("New ticket with \"%(date)s\" as the start date", date=tag.span('', data='start-date')), data_href=req.href('newticket', [(self.mod.start_date_name, '')]), class_='newticket-start-date')), tag.li(tag.a( tag_("New ticket with \"%(date)s\" as the due date", date=tag.span('', data='due-date')), data_href=req.href('newticket', [(self.mod.due_date_name, '')]), class_='newticket-due-date'))), title=_("Create new ticket"), class_='ticketcalendar-newticket-box', style='display:none', data_writable=(None, 'writable')[can_create]) class_ = ('ticketcalendar', 'ticketcalendar ticketcalendar-can-create')[can_create] return tag.div(header, calendar, ticket_box, class_=class_, style=width and ('width: %s' % width) or None)