# HG changeset patch # User Paul Boddie # Date 1237682766 -3600 # Node ID b3b01e7b369979eed6734345840330b8e47ba46f # Parent a45ac563d8c3fc55c1c8f6dcbec851d0a6081867 Introduced the recording of events by month, defining a monthrange function to handle common month sequence generation. Improved the layout, tidying up the list view and supporting automatic colouring of events in the calendar view. Added a sample template for events. diff -r a45ac563d8c3 -r b3b01e7b3699 css/event-aggregator.css --- a/css/event-aggregator.css Sat Mar 21 23:01:28 2009 +0100 +++ b/css/event-aggregator.css Sun Mar 22 01:46:06 2009 +0100 @@ -9,6 +9,8 @@ Licensed under the GNU GPL (v2 or later), see COPYING.txt for details. */ +/* Calendar view. */ + .event-month { width: 90%; } @@ -21,10 +23,14 @@ .event-day-heading { background-color: #9999ff; + text-align: center; } .event-day { width: 14%; + vertical-align: top; + padding-left: 0; + padding-top: 0; } .event-day-empty { @@ -32,19 +38,48 @@ } .event-day-busy { - background-color: #ff9999; + background-color: #ffffff; } .event-day-excluded { background-color: #dddddd; } -.event-day-empty .event-day-number { - color: #999999; +.event-day-empty span.event-day-number { + color: #000000; +} + +.event-day-busy span.event-day-number { + background-color: #555555; + color: #ffffff; +} + +.event-day-number { + padding: 0.25em; +} + +.event-summary { + padding: 0.25em; + margin-bottom: 0.25em; } -.event-day-busy .event-day-number,a:link,a:visited { - color: #000000; +.event-summary a:link, +.event-summary a:visited { + color: inherit; +} + +/* List/summary view. */ + +.event-listings { + list-style: none; +} + +.event-listings-month-heading { + border-bottom: 1px solid #999999; +} + +.event-month-listings { + list-style: disc; } /* vim: tabstop=4 expandtab shiftwidth=4 diff -r a45ac563d8c3 -r b3b01e7b3699 macros/EventAggregator.py --- a/macros/EventAggregator.py Sat Mar 21 23:01:28 2009 +0100 +++ b/macros/EventAggregator.py Sun Mar 22 01:46:06 2009 +0100 @@ -111,6 +111,43 @@ else: return None +def monthrange(first, last): + results = [] + + end_year = last[0] + + for year in range(first[0], end_year + 1): + if year < last[0]: + end_month = 12 + else: + end_month = last[1] + + if year > first[0]: + start_month = 1 + else: + start_month = first[1] + + for month in range(start_month, end_month + 1): + results.append((year, month)) + + return results + +def getColour(s): + colour = [0, 0, 0] + digit = 0 + for c in s: + colour[digit] += ord(c) + colour[digit] = colour[digit] % 256 + digit += 1 + digit = digit % 3 + return tuple(colour) + +def getBlackOrWhite(colour): + if sum(colour) / 3.0 > 127: + return (0, 0, 0) + else: + return (255, 255, 255) + def execute(macro, args): """ @@ -156,7 +193,8 @@ # categories, as found in the macro arguments. events = [] - shown_events = [] + shown_events = {} + earliest = None latest = None @@ -191,172 +229,204 @@ if (calendar_start is None or end_month >= calendar_start) and \ (calendar_end is None or start_month <= calendar_end): - shown_events.append(event) - if earliest is None or start_month < earliest: earliest = start_month if latest is None or end_month > latest: latest = end_month + # Store the event in the month-specific dictionary. + + first = max(start_month, calendar_start or start_month) + last = min(end_month, calendar_end or end_month) + + for event_month in monthrange(first, last): + if not shown_events.has_key(event_month): + shown_events[event_month] = [] + shown_events[event_month].append(event) + # Make a calendar. output = [] - if mode == "calendar": + if mode == "list": + output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"})) - first = calendar_start or earliest - last = calendar_end or latest + # Visit all months in the requested range, or across known events. - end_year = last[0] + first = calendar_start or earliest + last = calendar_end or latest - for year in range(first[0], end_year + 1): - if year < last[0]: - end_month = 12 - else: - end_month = last[1] + for year, month in monthrange(first, last): + + # Either output a calendar view... - if year > first[0]: - start_month = 1 - else: - start_month = first[1] + if mode == "calendar": + + # Output a month. + + output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"})) - for month in range(start_month, end_month + 1): + output.append(fmt.table_row(on=1)) + output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "7"})) + output.append(fmt.span(on=1)) + output.append(fmt.text(_(month_labels[month - 1]))) # zero-based labels + output.append(fmt.span(on=0)) + output.append(fmt.text(" ")) + output.append(fmt.span(on=1)) + output.append(fmt.text(year)) + output.append(fmt.span(on=0)) + output.append(fmt.table_cell(on=0)) + output.append(fmt.table_row(on=0)) - # Output a month. + # Weekday headings. - output.append(fmt.table(on=1, attrs={"tableclass" : "event-month"})) + output.append(fmt.table_row(on=1)) - output.append(fmt.table_row(on=1)) - output.append(fmt.table_cell(on=1, attrs={"class" : "event-month-heading", "colspan" : "7"})) - output.append(fmt.span(on=1)) - output.append(fmt.text(_(month_labels[month - 1]))) # zero-based labels - output.append(fmt.span(on=0)) - output.append(fmt.text(" ")) - output.append(fmt.span(on=1)) - output.append(fmt.text(year)) - output.append(fmt.span(on=0)) + for weekday in range(0, 7): + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading"})) + output.append(fmt.text(_(weekday_labels[weekday]))) output.append(fmt.table_cell(on=0)) - output.append(fmt.table_row(on=0)) + + output.append(fmt.table_row(on=0)) + + # Process the days of the month. + + start_weekday, number_of_days = calendar.monthrange(year, month) - # Weekday headings. + # 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 + + while first_day <= number_of_days: + + # Output a week. output.append(fmt.table_row(on=1)) for weekday in range(0, 7): - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading"})) - output.append(fmt.text(_(weekday_labels[weekday]))) - output.append(fmt.table_cell(on=0)) + day = first_day + weekday + + # Output out-of-month days. + + if day < 1 or day > number_of_days: + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-excluded"})) + output.append(fmt.table_cell(on=0)) + + # Output normal days. + + else: + # Get event details. + # NOTE: Can be made more efficient. + + date = (year, month, day) + day_events = [] + + for event_page, event_details in shown_events.get((year, month), []): + + # Test for the event on the current day. + + if event_details["start"] <= date <= event_details["end"]: + day_events.append((event_page, event_details)) + + # Output the day. + + if day_events: + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-busy"})) + else: + output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-empty"})) + + output.append(fmt.div(on=1)) + output.append(fmt.span(on=1, css_class="event-day-number")) + output.append(fmt.text(day)) + output.append(fmt.span(on=0)) + output.append(fmt.div(on=0)) + + output.append(fmt.div(on=1, css_class="event-summaries")) + + # Show event details. + + for event_page, event_details in day_events: + + # Get a pretty version of the page name. + + pretty_pagename = getPrettyPageName(event_page) + + # Generate a colour for the event. + + bg = getColour(event_page.page_name) + fg = getBlackOrWhite(bg) + + # Output the event. + + output.append(fmt.div(on=1, css_class="event-summary", + style=("background-color: rgb(%d, %d, %d); color: rgb(%d, %d, %d);" % (bg + fg)))) + output.append(event_page.link_to_raw(request, wikiutil.escape(pretty_pagename))) + output.append(fmt.div(on=0)) + + output.append(fmt.div(on=0)) + + # End of day. + + output.append(fmt.table_cell(on=0)) output.append(fmt.table_row(on=0)) - # Process the days of the month. - - start_weekday, number_of_days = calendar.monthrange(year, month) + first_day += 7 - # 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 - - while first_day <= number_of_days: + # End of month. - # Output a week. - - output.append(fmt.table_row(on=1)) + output.append(fmt.table(on=0)) - for weekday in range(0, 7): - day = first_day + weekday + # Or output a summary view... - # Output out-of-month days. - - if day < 1 or day > number_of_days: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-excluded"})) - output.append(fmt.table_cell(on=0)) + elif mode == "list": - # Output normal days. - - else: - # Get event details. - # NOTE: Can be made more efficient. - - date = (year, month, day) - day_events = [] - - for event_page, event_details in shown_events: - - # Test for the event on the current day. + output.append(fmt.listitem(on=1, attr={"class" : "event-listings-month"})) + output.append(fmt.div(on=1, attr={"class" : "event-listings-month-heading"})) + output.append(fmt.span(on=1)) + output.append(fmt.text(_(month_labels[month - 1]))) # zero-based labels + output.append(fmt.span(on=0)) + output.append(fmt.text(" ")) + output.append(fmt.span(on=1)) + output.append(fmt.text(year)) + output.append(fmt.span(on=0)) + output.append(fmt.div(on=0)) - if event_details["start"] <= date <= event_details["end"]: - day_events.append((event_page, event_details)) - - # Output the day. + output.append(fmt.bullet_list(on=1, attr={"class" : "event-month-listings"})) - if day_events: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-busy"})) - else: - output.append(fmt.table_cell(on=1, attrs={"class" : "event-day event-day-empty"})) + for event_page, event_details in shown_events.get((year, month), []): - output.append(fmt.div(on=1, css_class="event-day-number")) - output.append(fmt.text(day)) - output.append(fmt.div(on=0)) + # Get a pretty version of the page name. - # Show event details. - - for event_page, event_details in day_events: - - # Get a pretty version of the page name. + pretty_pagename = getPrettyPageName(event_page) - pretty_pagename = getPrettyPageName(event_page) + output.append(fmt.listitem(on=1, attr={"class" : "event-listing"})) - # Output the event. - - output.append(event_page.link_to_raw(request, wikiutil.escape(pretty_pagename))) - output.append(fmt.linebreak()) + # Link to the page using the pretty name. - # End of day. - - output.append(fmt.table_cell(on=0)) - - output.append(fmt.table_row(on=0)) + output.append(event_page.link_to_raw(request, wikiutil.escape(pretty_pagename))) - first_day += 7 - - # End of month. + # Add the event details. - output.append(fmt.table(on=0)) - - elif mode == "list": - output.append(fmt.bullet_list(on=1, attr={"class" : "event-listings"})) + output.append(fmt.definition_list(on=1, attr={"class" : "event-details"})) - for event_page, event_details in shown_events: - - # Get a pretty version of the page name. - - pretty_pagename = getPrettyPageName(event_page) - - output.append(fmt.listitem(on=1, attr={"class" : "event-listing"})) - - # Link to the page using the pretty name. - - output.append(event_page.link_to_raw(request, wikiutil.escape(pretty_pagename))) - - # Add the event details. + for key, value in event_details.items(): + output.append(fmt.definition_term(on=1)) + output.append(fmt.text(key)) + output.append(fmt.definition_term(on=0)) + output.append(fmt.definition_desc(on=1)) + output.append(fmt.text(value)) + output.append(fmt.definition_desc(on=0)) - output.append(fmt.definition_list(on=1, attr={"class" : "event-details"})) + output.append(fmt.definition_list(on=0)) + output.append(fmt.listitem(on=0)) - for key, value in event_details.items(): - output.append(fmt.definition_term(on=1)) - output.append(fmt.text(key)) - output.append(fmt.definition_term(on=0)) - output.append(fmt.definition_desc(on=1)) - output.append(fmt.text(value)) - output.append(fmt.definition_desc(on=0)) + output.append(fmt.bullet_list(on=0)) - output.append(fmt.definition_list(on=0)) - output.append(fmt.listitem(on=0)) - + if mode == "list": output.append(fmt.bullet_list(on=0)) return ''.join(output) diff -r a45ac563d8c3 -r b3b01e7b3699 pages/EventTemplate --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/EventTemplate Sun Mar 22 01:46:06 2009 +0100 @@ -0,0 +1,7 @@ + Start:: YYYY-MM-DD + End:: YYYY-MM-DD + Topics:: topics + +Description of event. +---- +CategoryEvents