# HG changeset patch # User Paul Boddie # Date 1257644966 -3600 # Node ID 8212216604482106f77dc6d942c6b833ce600f38 # Parent 7d7a4577ceb1ad2be689999802b2729f0b0eece9 Fixed the table view by just showing all events in the chosen period, not traversing each month and showing that month's events, which leads to events being duplicated if they span month boundaries. diff -r 7d7a4577ceb1 -r 821221660448 macros/EventAggregator.py --- a/macros/EventAggregator.py Sat Nov 07 22:28:16 2009 +0100 +++ b/macros/EventAggregator.py Sun Nov 08 02:49:26 2009 +0100 @@ -385,18 +385,11 @@ output.append(view.writeDownloadControls()) output.append(fmt.div(on=0)) - # Output top-level information. - - # Start of list view output. + # Output a table. - if mode == "list": - output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"})) + if mode == "table": - # Start of table view output. - - elif mode == "table": - - # Output a table. + # Start of table view output. output.append(fmt.table(on=1, attrs={"tableclass" : "event-table"})) @@ -412,100 +405,134 @@ output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) - # Visit all months in the requested range, or across known events. + # Get the events in order. - for year, month in EventAggregatorSupport.daterange(first, last): - - # Either output a calendar view... + ordered_events = EventAggregatorSupport.getOrderedEvents(all_shown_events) - if mode == "calendar": + # Show the events in order. - # Output a month. - - output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"})) + for event_page, event_details in ordered_events: + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) - output.append(fmt.table_row(on=1)) - output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "21"})) + # Prepare CSS classes with category-related styling. - # Either write a month heading or produce links for navigable - # calendars. + css_classes = ["event-table-details"] + + for topic in event_details.get("topics") or event_details.get("categories") or []: - output.append(view.writeMonthHeading(year, month)) + # Filter the category text to avoid illegal characters. - output.append(fmt.table_cell(on=0)) - output.append(fmt.table_row(on=0)) + css_classes.append("event-table-category-%s" % "".join(filter(lambda c: c.isalnum(), topic))) - # Weekday headings. + attrs = {"class" : " ".join(css_classes)} output.append(fmt.table_row(on=1)) - for weekday in range(0, 7): - output.append(fmt.table_cell(on=1, attrs={"class" : "event-weekday-heading", "colspan" : "3"})) - output.append(fmt.text(_(EventAggregatorSupport.getDayLabel(weekday)))) - output.append(fmt.table_cell(on=0)) + # Start and end dates. + + output.append(fmt.table_cell(on=1, attrs=attrs)) + output.append(fmt.span(on=1)) + output.append(fmt.text("%04d-%02d-%02d" % event_details["start"])) + output.append(fmt.span(on=0)) + + if event_details["start"] != event_details["end"]: + output.append(fmt.text(" - ")) + output.append(fmt.span(on=1)) + output.append(fmt.text("%04d-%02d-%02d" % event_details["end"])) + output.append(fmt.span(on=0)) + + output.append(fmt.table_cell(on=0)) + + # Location. + + output.append(fmt.table_cell(on=1, attrs=attrs)) + + if event_details.has_key("location"): + output.append(fmt.text(event_details["location"])) + + output.append(fmt.table_cell(on=0)) + + # Link to the page using the summary. + + output.append(fmt.table_cell(on=1, attrs=attrs)) + output.append(linkToPage(request, event_page, event_summary)) + output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) - # Process the days of the month. + # End of table view output. + + output.append(fmt.table(on=0)) - start_weekday, number_of_days = calendar.monthrange(year, month) + # Output a list or calendar. + + elif mode in ("list", "calendar"): - # The start weekday is the weekday of day number 1. - # Find the first day of the week, counting from below zero, if - # necessary, in order to land on the first day of the month as - # day number 1. + # Output top-level information. + + # Start of list view output. - first_day = 1 - start_weekday + if mode == "list": + output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"})) + + # Visit all months in the requested range, or across known events. + + for year, month in EventAggregatorSupport.daterange(first, last): - while first_day <= number_of_days: + # Either output a calendar view... + + if mode == "calendar": - # Find events in this week and determine how to mark them on the - # calendar. + # Output a month. + + output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"})) - week_start = (year, month, max(first_day, 1)) - week_end = (year, month, min(first_day + 6, number_of_days)) + output.append(fmt.table_row(on=1)) + output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "21"})) + + # Either write a month heading or produce links for navigable + # calendars. - week_coverage, week_events = EventAggregatorSupport.getCoverage( - week_start, week_end, shown_events.get((year, month), [])) + output.append(view.writeMonthHeading(year, month)) - # Output a week, starting with the day numbers. + output.append(fmt.table_cell(on=0)) + output.append(fmt.table_row(on=0)) + + # Weekday headings. output.append(fmt.table_row(on=1)) for weekday in range(0, 7): - day = first_day + weekday - date = (year, month, day) - - # Output out-of-month days. - - if day < 1 or day > number_of_days: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading event-day-excluded", "colspan" : "3"})) - output.append(fmt.table_cell(on=0)) - - # Output normal days. - - else: - if date in week_coverage: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading event-day-busy", "colspan" : "3"})) - else: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading event-day-empty", "colspan" : "3"})) - - # Output the day number, making a link to a new event - # action. - - output.append(view.writeDayNumberLinked(day, month, year)) - - # End of day. - - output.append(fmt.table_cell(on=0)) - - # End of day numbers. + output.append(fmt.table_cell(on=1, attrs={"class" : "event-weekday-heading", "colspan" : "3"})) + output.append(fmt.text(_(EventAggregatorSupport.getDayLabel(weekday)))) + output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) - # Either generate empty days... + # Process the days of the month. + + start_weekday, number_of_days = calendar.monthrange(year, month) + + # The start weekday is the weekday of day number 1. + # Find the first day of the week, counting from below zero, if + # necessary, in order to land on the first day of the month as + # day number 1. + + first_day = 1 - start_weekday - if not week_events: + while first_day <= number_of_days: + + # Find events in this week and determine how to mark them on the + # calendar. + + week_start = (year, month, max(first_day, 1)) + week_end = (year, month, min(first_day + 6, number_of_days)) + + week_coverage, week_events = EventAggregatorSupport.getCoverage( + week_start, week_end, shown_events.get((year, month), [])) + + # Output a week, starting with the day numbers. + output.append(fmt.table_row(on=1)) for weekday in range(0, 7): @@ -516,376 +543,351 @@ if day < 1 or day > number_of_days: output.append(fmt.table_cell(on=1, - attrs={"class" : "event-day-content event-day-excluded", "colspan" : "3"})) + attrs={"class" : "event-day-heading event-day-excluded", "colspan" : "3"})) output.append(fmt.table_cell(on=0)) - # Output empty days. + # Output normal days. else: - output.append(fmt.table_cell(on=1, - attrs={"class" : "event-day-content event-day-empty", "colspan" : "3"})) + if date in week_coverage: + output.append(fmt.table_cell(on=1, + attrs={"class" : "event-day-heading event-day-busy", "colspan" : "3"})) + else: + output.append(fmt.table_cell(on=1, + attrs={"class" : "event-day-heading event-day-empty", "colspan" : "3"})) + + # Output the day number, making a link to a new event + # action. + + output.append(view.writeDayNumberLinked(day, month, year)) + + # End of day. + + output.append(fmt.table_cell(on=0)) + + # End of day numbers. output.append(fmt.table_row(on=0)) - # Or visit each set of scheduled events... - - else: - for coverage, events in week_events: + # Either generate empty days... - # Output each set. - + if not week_events: output.append(fmt.table_row(on=1)) - # Then, output day details. - for weekday in range(0, 7): day = first_day + weekday date = (year, month, day) - # Skip out-of-month days. + # Output out-of-month days. if day < 1 or day > number_of_days: output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-content event-day-excluded", "colspan" : "3"})) output.append(fmt.table_cell(on=0)) - continue - # Output the day. + # Output empty days. - if date not in coverage: + else: output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-content event-day-empty", "colspan" : "3"})) - # Get event details for the current day. + output.append(fmt.table_row(on=0)) + + # Or visit each set of scheduled events... + + else: + for coverage, events in week_events: + + # Output each set. + + output.append(fmt.table_row(on=1)) - for event_page, event_details in events: - if not (event_details["start"] <= date <= event_details["end"]): + # Then, output day details. + + for weekday in range(0, 7): + day = first_day + weekday + date = (year, month, day) + + # Skip out-of-month days. + + if day < 1 or day > number_of_days: + output.append(fmt.table_cell(on=1, + attrs={"class" : "event-day-content event-day-excluded", "colspan" : "3"})) + output.append(fmt.table_cell(on=0)) continue - # Get basic properties of the event. + # Output the day. - starts_today = event_details["start"] == date - ends_today = event_details["end"] == date - event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) + if date not in coverage: + output.append(fmt.table_cell(on=1, + attrs={"class" : "event-day-content event-day-empty", "colspan" : "3"})) - # Generate a colour for the event. + # Get event details for the current day. - bg = getColour(event_page.page_name) - fg = getBlackOrWhite(bg) - style = ("background-color: rgb(%d, %d, %d); color: rgb(%d, %d, %d);" % (bg + fg)) + for event_page, event_details in events: + if not (event_details["start"] <= date <= event_details["end"]): + continue - # Determine if the event name should be shown. + # Get basic properties of the event. - start_of_period = starts_today or weekday == 0 or day == 1 + starts_today = event_details["start"] == date + ends_today = event_details["end"] == date + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) - if name_usage == "daily" or start_of_period: - hide_text = 0 - else: - hide_text = 1 + # Generate a colour for the event. - # Output start of day gap and determine whether - # any event content should be explicitly output - # for this day. + bg = getColour(event_page.page_name) + fg = getBlackOrWhite(bg) + style = ("background-color: rgb(%d, %d, %d); color: rgb(%d, %d, %d);" % (bg + fg)) - if starts_today: + # Determine if the event name should be shown. - # Single day events... + start_of_period = starts_today or weekday == 0 or day == 1 - if ends_today: - colspan = 3 - event_day_type = "event-day-single" + if name_usage == "daily" or start_of_period: + hide_text = 0 + else: + hide_text = 1 - # Events starting today... + # Output start of day gap and determine whether + # any event content should be explicitly output + # for this day. - else: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-start-gap"})) - output.append(fmt.table_cell(on=0)) + if starts_today: - # Calculate the span of this cell. - # Events whose names appear on every day... + # Single day events... - if name_usage == "daily": - colspan = 2 - event_day_type = "event-day-starting" + if ends_today: + colspan = 3 + event_day_type = "event-day-single" - # Events whose names appear once per week... + # Events starting today... else: - if event_details["end"] <= week_end: - event_length = event_details["end"][2] - day + 1 - colspan = (event_length - 2) * 3 + 4 + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-start-gap"})) + output.append(fmt.table_cell(on=0)) + + # Calculate the span of this cell. + # Events whose names appear on every day... + + if name_usage == "daily": + colspan = 2 + event_day_type = "event-day-starting" + + # Events whose names appear once per week... + else: - event_length = week_end[2] - day + 1 - colspan = (event_length - 1) * 3 + 2 + if event_details["end"] <= week_end: + event_length = event_details["end"][2] - day + 1 + colspan = (event_length - 2) * 3 + 4 + else: + event_length = week_end[2] - day + 1 + colspan = (event_length - 1) * 3 + 2 - event_day_type = "event-day-multiple" + event_day_type = "event-day-multiple" + + # Events continuing from a previous week... - # Events continuing from a previous week... + elif start_of_period: - elif start_of_period: + # End of continuing event... - # End of continuing event... + if ends_today: + colspan = 2 + event_day_type = "event-day-ending" + + # Events continuing for at least one more day... + + else: - if ends_today: - colspan = 2 - event_day_type = "event-day-ending" + # Calculate the span of this cell. + # Events whose names appear on every day... + + if name_usage == "daily": + colspan = 3 + event_day_type = "event-day-full" + + # Events whose names appear once per week... - # Events continuing for at least one more day... - - else: + else: + if event_details["end"] <= week_end: + event_length = event_details["end"][2] - day + 1 + colspan = (event_length - 1) * 3 + 2 + else: + event_length = week_end[2] - day + 1 + colspan = event_length * 3 - # Calculate the span of this cell. - # Events whose names appear on every day... + event_day_type = "event-day-multiple" + + # Continuing events whose names appear on every day... - if name_usage == "daily": + elif name_usage == "daily": + if ends_today: + colspan = 2 + event_day_type = "event-day-ending" + else: colspan = 3 event_day_type = "event-day-full" - # Events whose names appear once per week... + # Continuing events whose names appear once per week... + + else: + colspan = None - else: - if event_details["end"] <= week_end: - event_length = event_details["end"][2] - day + 1 - colspan = (event_length - 1) * 3 + 2 - else: - event_length = week_end[2] - day + 1 - colspan = event_length * 3 + # Output the main content only if it is not + # continuing from a previous day. - event_day_type = "event-day-multiple" + if colspan is not None: - # Continuing events whose names appear on every day... + # Colour the cell for continuing events. - elif name_usage == "daily": - if ends_today: - colspan = 2 - event_day_type = "event-day-ending" - else: - colspan = 3 - event_day_type = "event-day-full" + attrs={ + "class" : "event-day-content event-day-busy %s" % event_day_type, + "colspan" : str(colspan) + } - # Continuing events whose names appear once per week... - - else: - colspan = None + if not (starts_today and ends_today): + attrs["style"] = style - # Output the main content only if it is not - # continuing from a previous day. - - if colspan is not None: - - # Colour the cell for continuing events. + output.append(fmt.table_cell(on=1, attrs=attrs)) - attrs={ - "class" : "event-day-content event-day-busy %s" % event_day_type, - "colspan" : str(colspan) - } + # Output the event. - if not (starts_today and ends_today): - attrs["style"] = style + if starts_today and ends_today or not hide_text: - output.append(fmt.table_cell(on=1, attrs=attrs)) + output.append(fmt.div(on=1, css_class="event-summary-box")) + output.append(fmt.div(on=1, css_class="event-summary", style=style)) + output.append(linkToPage(request, event_page, event_summary)) + output.append(fmt.div(on=0)) - # Output the event. - - if starts_today and ends_today or not hide_text: + # Add a pop-up element for long summaries. - output.append(fmt.div(on=1, css_class="event-summary-box")) - output.append(fmt.div(on=1, css_class="event-summary", style=style)) - output.append(linkToPage(request, event_page, event_summary)) - output.append(fmt.div(on=0)) + output.append(fmt.div(on=1, css_class="event-summary-popup", style=style)) + output.append(linkToPage(request, event_page, event_summary)) + output.append(fmt.div(on=0)) - # Add a pop-up element for long summaries. + output.append(fmt.div(on=0)) - output.append(fmt.div(on=1, css_class="event-summary-popup", style=style)) - output.append(linkToPage(request, event_page, event_summary)) - output.append(fmt.div(on=0)) + # Output end of day content. output.append(fmt.div(on=0)) - # Output end of day content. - - output.append(fmt.div(on=0)) - - # Output end of day gap. + # Output end of day gap. - if ends_today and not starts_today: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-end-gap"})) - output.append(fmt.table_cell(on=0)) - - # End of day. + if ends_today and not starts_today: + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-end-gap"})) + output.append(fmt.table_cell(on=0)) - output.append(fmt.table_cell(on=0)) - - # End of set. - - output.append(fmt.table_row(on=0)) + # End of day. - # Add a spacer. - - output.append(fmt.table_row(on=1)) + output.append(fmt.table_cell(on=0)) - for weekday in range(0, 7): - day = first_day + weekday - css_classes = "event-day-spacer" + # End of set. - # Skip out-of-month days. - - if day < 1 or day > number_of_days: - css_classes += " event-day-excluded" + output.append(fmt.table_row(on=0)) - output.append(fmt.table_cell(on=1, attrs={"class" : css_classes, "colspan" : "3"})) - output.append(fmt.table_cell(on=0)) + # Add a spacer. - output.append(fmt.table_row(on=0)) + output.append(fmt.table_row(on=1)) - # Process the next week... - - first_day += 7 - - # End of month. - - output.append(fmt.table(on=0)) + for weekday in range(0, 7): + day = first_day + weekday + css_classes = "event-day-spacer" - # Or output a summary view... - - elif mode == "list": + # Skip out-of-month days. - # Output a list. - - output.append(fmt.listitem(on=1, attr={"class" : "event-listings-month"})) - output.append(fmt.div(on=1, attr={"class" : "event-listings-month-heading"})) + if day < 1 or day > number_of_days: + css_classes += " event-day-excluded" - # Either write a month heading or produce links for navigable - # calendars. - - output.append(view.writeMonthHeading(year, month)) + output.append(fmt.table_cell(on=1, attrs={"class" : css_classes, "colspan" : "3"})) + output.append(fmt.table_cell(on=0)) - output.append(fmt.div(on=0)) - - output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"})) - - # Get the events in order. + output.append(fmt.table_row(on=0)) - ordered_events = EventAggregatorSupport.getOrderedEvents(shown_events.get((year, month), [])) + # Process the next week... - # Show the events in order. + first_day += 7 - for event_page, event_details in ordered_events: - event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) + # End of month. - output.append(fmt.listitem(on=1, attr={"class" : "event-listing"})) - - # Link to the page using the summary. + output.append(fmt.table(on=0)) - output.append(fmt.paragraph(on=1)) - output.append(linkToPage(request, event_page, event_summary)) - output.append(fmt.paragraph(on=0)) + # Or output a summary view... - # Start and end dates. + elif mode == "list": - output.append(fmt.paragraph(on=1)) - output.append(fmt.span(on=1)) - output.append(fmt.text("%04d-%02d-%02d" % event_details["start"])) - output.append(fmt.span(on=0)) - output.append(fmt.text(" - ")) - output.append(fmt.span(on=1)) - output.append(fmt.text("%04d-%02d-%02d" % event_details["end"])) - output.append(fmt.span(on=0)) - output.append(fmt.paragraph(on=0)) + # Output a list. - # Location. + output.append(fmt.listitem(on=1, attr={"class" : "event-listings-month"})) + output.append(fmt.div(on=1, attr={"class" : "event-listings-month-heading"})) - if event_details.has_key("location"): - output.append(fmt.paragraph(on=1)) - output.append(fmt.text(event_details["location"])) - output.append(fmt.paragraph(on=1)) + # Either write a month heading or produce links for navigable + # calendars. - # Topics. + output.append(view.writeMonthHeading(year, month)) - if event_details.has_key("topics") or event_details.has_key("categories"): - output.append(fmt.bullet_list(on=1, attr={"class" : "event-topics"})) + output.append(fmt.div(on=0)) - for topic in event_details.get("topics") or event_details.get("categories") or []: - output.append(fmt.listitem(on=1)) - output.append(fmt.text(topic)) - output.append(fmt.listitem(on=0)) + output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"})) - output.append(fmt.bullet_list(on=0)) - - output.append(fmt.listitem(on=0)) + # Get the events in order. - output.append(fmt.bullet_list(on=0)) - - # Or output a table of events... + ordered_events = EventAggregatorSupport.getOrderedEvents(shown_events.get((year, month), [])) - elif mode == "table": - - # Get the events in order. + # Show the events in order. - ordered_events = EventAggregatorSupport.getOrderedEvents(shown_events.get((year, month), [])) - - # Show the events in order. + for event_page, event_details in ordered_events: + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) - for event_page, event_details in ordered_events: - event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details, parent_name) + output.append(fmt.listitem(on=1, attr={"class" : "event-listing"})) - # Prepare CSS classes with category-related styling. - - css_classes = ["event-table-details"] + # Link to the page using the summary. - for topic in event_details.get("topics") or event_details.get("categories") or []: - - # Filter the category text to avoid illegal characters. - - css_classes.append("event-table-category-%s" % "".join(filter(lambda c: c.isalnum(), topic))) - - attrs = {"class" : " ".join(css_classes)} + output.append(fmt.paragraph(on=1)) + output.append(linkToPage(request, event_page, event_summary)) + output.append(fmt.paragraph(on=0)) - output.append(fmt.table_row(on=1)) - - # Start and end dates. + # Start and end dates. - output.append(fmt.table_cell(on=1, attrs=attrs)) - output.append(fmt.span(on=1)) - output.append(fmt.text("%04d-%02d-%02d" % event_details["start"])) - output.append(fmt.span(on=0)) - - if event_details["start"] != event_details["end"]: + output.append(fmt.paragraph(on=1)) + output.append(fmt.span(on=1)) + output.append(fmt.text("%04d-%02d-%02d" % event_details["start"])) + output.append(fmt.span(on=0)) output.append(fmt.text(" - ")) output.append(fmt.span(on=1)) output.append(fmt.text("%04d-%02d-%02d" % event_details["end"])) output.append(fmt.span(on=0)) - - output.append(fmt.table_cell(on=0)) + output.append(fmt.paragraph(on=0)) - # Location. - - output.append(fmt.table_cell(on=1, attrs=attrs)) + # Location. - if event_details.has_key("location"): - output.append(fmt.text(event_details["location"])) + if event_details.has_key("location"): + output.append(fmt.paragraph(on=1)) + output.append(fmt.text(event_details["location"])) + output.append(fmt.paragraph(on=1)) - output.append(fmt.table_cell(on=0)) + # Topics. - # Link to the page using the summary. + if event_details.has_key("topics") or event_details.has_key("categories"): + output.append(fmt.bullet_list(on=1, attr={"class" : "event-topics"})) - output.append(fmt.table_cell(on=1, attrs=attrs)) - output.append(linkToPage(request, event_page, event_summary)) - output.append(fmt.table_cell(on=0)) + for topic in event_details.get("topics") or event_details.get("categories") or []: + output.append(fmt.listitem(on=1)) + output.append(fmt.text(topic)) + output.append(fmt.listitem(on=0)) - output.append(fmt.table_row(on=0)) + output.append(fmt.bullet_list(on=0)) - # Output top-level information. + output.append(fmt.listitem(on=0)) - # End of list view output. + output.append(fmt.bullet_list(on=0)) - if mode == "list": - output.append(fmt.bullet_list(on=0)) + # Output top-level information. - # End of table view output. + # End of list view output. - elif mode == "table": - output.append(fmt.table(on=0)) + if mode == "list": + output.append(fmt.bullet_list(on=0)) # Output view controls.