1.1 --- a/EventAggregatorSupport.py Sun Mar 29 21:01:49 2009 +0200
1.2 +++ b/EventAggregatorSupport.py Sun Mar 29 22:34:33 2009 +0200
1.3 @@ -10,8 +10,10 @@
1.4
1.5 from MoinMoin.Page import Page
1.6 from MoinMoin import search, version
1.7 +from MoinMoin import wikiutil
1.8 import calendar
1.9 import datetime
1.10 +import time
1.11 import re
1.12
1.13 __version__ = "0.1"
1.14 @@ -86,6 +88,14 @@
1.15 mapping.sort()
1.16 return mapping
1.17
1.18 +def getPageDate(page):
1.19 +
1.20 + # From MoinMoin.xmlrpc...
1.21 +
1.22 + edit_info = page.edit_info()
1.23 + mtime = wikiutil.version2timestamp(long(edit_info['timestamp'])) # must be long for py 2.2.x
1.24 + return tuple(time.gmtime(mtime))
1.25 +
1.26 # The main activity functions.
1.27
1.28 def getPages(pagename, request):
1.29 @@ -106,6 +116,18 @@
1.30 pages.append(page)
1.31 return pages
1.32
1.33 +def getSimpleWikiText(text):
1.34 +
1.35 + """
1.36 + Return the plain text representation of the given 'text' which may employ
1.37 + certain Wiki syntax features, such as those providing verbatim or monospaced
1.38 + text.
1.39 + """
1.40 +
1.41 + # NOTE: Re-implementing support for verbatim text and linking avoidance.
1.42 +
1.43 + return "".join([s for s in verbatim_regexp.split(text) if s is not None])
1.44 +
1.45 def getEventDetails(page):
1.46
1.47 "Return a dictionary of event details from the given 'page'."
1.48 @@ -127,17 +149,15 @@
1.49 if term in ("start", "end"):
1.50 desc = getDate(desc)
1.51
1.52 - # Lists.
1.53 + # Lists (whose elements may be quoted).
1.54
1.55 - elif term in ("topics",):
1.56 - desc = [value.strip() for value in desc.split(",")]
1.57 + elif term in ("topics", "categories"):
1.58 + desc = [getSimpleWikiText(value.strip()) for value in desc.split(",")]
1.59
1.60 # Labels which may well be quoted.
1.61 - # NOTE: Re-implementing support for verbatim text and linking
1.62 - # NOTE: avoidance.
1.63
1.64 elif term in ("title", "summary"):
1.65 - desc = "".join([s for s in verbatim_regexp.split(desc) if s is not None])
1.66 + desc = getSimpleWikiText(desc)
1.67
1.68 if desc is not None:
1.69 event_details[term] = desc
2.1 --- a/README.txt Sun Mar 29 21:01:49 2009 +0200
2.2 +++ b/README.txt Sun Mar 29 22:34:33 2009 +0200
2.3 @@ -90,17 +90,9 @@
2.4
2.5 To obtain an iCalendar summary, the EventAggregatorSummary action can be
2.6 selected from the actions menu on any page. Alternatively, a collection of
2.7 -parameters can be specified in the URL of any Wiki page. For example:
2.8 -
2.9 - http://example.com/moin/FrontPage?action=EventAggregatorSummary&category=CategoryEvents&doit=1
2.10 +parameters can be specified in the URL of any Wiki page.
2.11
2.12 -This should produce an iCalendar resource in response. By specifying 'start'
2.13 -and 'end' parameters, a restricted view can be obtained. For example:
2.14 -
2.15 - http://example.com/moin/FrontPage?action=EventAggregatorSummary&category=CategoryEvents&start=2009-06&end=2009-07&doit=1
2.16 -
2.17 -This would restrict the initial query to events occurring in the months of
2.18 -June 2009 ('2009-06') and July 2009 ('2009-07').
2.19 +See pages/HelpOnEventAggregatorSummary for more detailed information.
2.20
2.21 Recommended Software
2.22 --------------------
3.1 --- a/actions/EventAggregatorSummary.py Sun Mar 29 21:01:49 2009 +0200
3.2 +++ b/actions/EventAggregatorSummary.py Sun Mar 29 22:34:33 2009 +0200
3.3 @@ -4,13 +4,15 @@
3.4
3.5 @copyright: 2008, 2009 by Paul Boddie <paul@boddie.org.uk>
3.6 @copyright: 2000-2004 Juergen Hermann <jh@web.de>,
3.7 - 2005-2008 MoinMoin:ThomasWaldmann,
3.8 + 2003-2008 MoinMoin:ThomasWaldmann,
3.9 + 2004-2006 MoinMoin:AlexanderSchremmer,
3.10 2007 MoinMoin:ReimarBauer.
3.11 @license: GNU GPL (v2 or later), see COPYING.txt for details.
3.12 """
3.13
3.14 from MoinMoin.action import ActionBase
3.15 from MoinMoin import config
3.16 +from MoinMoin.Page import Page
3.17 import EventAggregatorSupport
3.18
3.19 Dependencies = ['pages']
3.20 @@ -118,6 +120,12 @@
3.21
3.22 pass
3.23
3.24 +def getQuotedText(text):
3.25 +
3.26 + "Return the 'text' quoted for iCalendar purposes."
3.27 +
3.28 + return text.replace(";", r"\;").replace(",", r"\,")
3.29 +
3.30 def write_resource(request):
3.31
3.32 """
3.33 @@ -157,18 +165,42 @@
3.34
3.35 for event_page, event_details in all_shown_events:
3.36
3.37 + # Get the summary and timestamp details.
3.38 +
3.39 event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)
3.40
3.41 + # Get the initial revision of the page.
3.42 +
3.43 + revisions = event_page.getRevList()
3.44 + event_page_initial = Page(request, event_page.page_name, rev=revisions[-1])
3.45 +
3.46 + # Get the created and last modified times.
3.47 +
3.48 + created = EventAggregatorSupport.getPageDate(event_page_initial)
3.49 + last_modified = EventAggregatorSupport.getPageDate(event_page)
3.50 + sequence = len(revisions) - 1
3.51 +
3.52 # Output the event details.
3.53
3.54 request.write("BEGIN:VEVENT\r\n")
3.55 - request.write("SUMMARY:%s\r\n" % event_summary)
3.56 request.write("UID:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.57 request.write("URL:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.58 + request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % created[:6])
3.59 + request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % last_modified[:6])
3.60 + request.write("SEQUENCE:%d\r\n" % sequence)
3.61 request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"])
3.62 request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"]))
3.63 - if event_details.has_key("topics"):
3.64 - request.write("CATEGORIES:%s\r\n" % ",".join(event_details["topics"]))
3.65 + request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary))
3.66 +
3.67 + # Optional details.
3.68 +
3.69 + if event_details.has_key("topics") or event_details.has_key("categories"):
3.70 + request.write("CATEGORIES:%s\r\n" % ",".join(
3.71 + [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")]
3.72 + ))
3.73 + if event_details.has_key("location"):
3.74 + request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"]))
3.75 +
3.76 request.write("END:VEVENT\r\n")
3.77
3.78 request.write("END:VCALENDAR\r\n")
4.1 --- a/css/event-aggregator.css Sun Mar 29 21:01:49 2009 +0200
4.2 +++ b/css/event-aggregator.css Sun Mar 29 22:34:33 2009 +0200
4.3 @@ -12,7 +12,7 @@
4.4 /* Calendar view. */
4.5
4.6 .event-month {
4.7 - width: 90%;
4.8 + width: 98%;
4.9 border-bottom: 1px solid #dddddd;
4.10 }
4.11
5.1 --- a/docs/COPYING.txt Sun Mar 29 21:01:49 2009 +0200
5.2 +++ b/docs/COPYING.txt Sun Mar 29 22:34:33 2009 +0200
5.3 @@ -3,13 +3,15 @@
5.4
5.5 Copyright (C) 2008, 2009 Paul Boddie <paul@boddie.org.uk>
5.6
5.7 -Some pieces of MoinMoin code were used in this work -
5.8 -specifically the category regular expression code from
5.9 -MoinMoin.config.multiconfig - and are thus covered by the
5.10 -following copyrights:
5.11 +Some pieces of MoinMoin code were used in this work - typically
5.12 +pieces which demonstrate how to perform certain common tasks
5.13 +(as found in various macros and actions) - and are thus covered
5.14 +by the following copyrights:
5.15
5.16 Copyright (C) 2000-2004 Juergen Hermann <jh@web.de>
5.17 -Copyright (C) 2005-2008 MoinMoin:ThomasWaldmann
5.18 +Copyright (C) 2003-2008 MoinMoin:ThomasWaldmann
5.19 +Copyright (C) 2004-2006 MoinMoin:AlexanderSchremmer
5.20 +Copyright (C) 2007 MoinMoin:ReimarBauer
5.21
5.22 This software is free software; you can redistribute it and/or
5.23 modify it under the terms of the GNU General Public License as
6.1 --- a/pages/HelpOnEventAggregator Sun Mar 29 21:01:49 2009 +0200
6.2 +++ b/pages/HelpOnEventAggregator Sun Mar 29 22:34:33 2009 +0200
6.3 @@ -33,6 +33,25 @@
6.4
6.5 Obviously, duplicating the date information introduces a risk of this information becoming inconsistent, so beware!
6.6
6.7 +=== Supported Event Properties ===
6.8 +
6.9 +As well as the start and end dates of an event, the following properties are also recognised as being part of an event description:
6.10 +
6.11 + Title:: the preferred name of the event in the calendar
6.12 + Summary:: a synonym for title
6.13 + Topics:: a list of topics related to the event - use a comma (`,`) to separate topic names
6.14 + Categories:: a synonym for topics
6.15 + Location:: the location of the event
6.16 +
6.17 +These properties may be incorporated into representations or summaries of events.
6.18 +
6.19 +Textual properties can be quoted in a limited way using the verbatim or monospaced text Wiki syntax. For example:
6.20 +
6.21 +{{{
6.22 + Summary:: <<Verbatim(EuroPython)>> 2009
6.23 + Topics:: Python, <<Verbatim(EuroPython)>>, Zope
6.24 +}}}
6.25 +
6.26 == Showing Event Calendars ==
6.27
6.28 To show a calendar, use the !EventAggregator macro with a list of event categories. For example:
6.29 @@ -80,3 +99,7 @@
6.30 }}}
6.31
6.32 The `list` value causes a list view to be employed; the `calendar` value causes the default calendar view to be employed.
6.33 +
6.34 +== See Also ==
6.35 +
6.36 + * HelpOnEventAggregatorSummary - an action producing iCalendar event summaries
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/pages/HelpOnEventAggregatorSummary Sun Mar 29 22:34:33 2009 +0200
7.3 @@ -0,0 +1,41 @@
7.4 +##master-page:HelpTemplate
7.5 +##master-date:Unknown-Date
7.6 +#format wiki
7.7 +#language en
7.8 +
7.9 +== EventAggregatorSummary ==
7.10 +
7.11 +The !EventAggregatorSummary action provides iCalendar summaries of events whose details are recorded in pages belonging to specific categories (such as CategoryEvents). These summaries can then be imported into applications which understand the iCalendar format.
7.12 +
7.13 +Upon invoking the action, an iCalendar response will be produced. If the action is invoked in a browser, it is most likely that a dialogue box will appear asking you whether you would like to save the response to a file or to open the response in a suitable application. This behaviour is slightly different to many !MoinMoin actions.
7.14 +
7.15 +== Using the Actions Menu Entry ==
7.16 +
7.17 +The action can be selected from the actions menu on any page; this will produce a form requesting values for the following items:
7.18 +
7.19 + * The names of categories known to the Wiki.
7.20 + * The start (first month) of the summary (optional).
7.21 + * The end (last month) of the summary (optional).
7.22 +
7.23 +Where no start or end values are specified, all events in the chosen categories are included in the summary.
7.24 +
7.25 +== Making Direct Requests to the Action ==
7.26 +
7.27 +Alternatively, a collection of parameters can be specified in the URL of any Wiki page. For example:
7.28 +
7.29 +{{{
7.30 +http://example.com/moin/FrontPage?action=EventAggregatorSummary&category=CategoryEvents&doit=1
7.31 +}}}
7.32 +
7.33 +This should produce an iCalendar resource in response. By specifying `start` and `end` parameters, a restricted view can be obtained. For example:
7.34 +
7.35 +{{{
7.36 +http://example.com/moin/FrontPage?action=EventAggregatorSummary&category=CategoryEvents
7.37 +&start=2009-06&end=2009-07&doit=1
7.38 +}}}
7.39 +
7.40 +This restricts the initial query to only retrieve events occurring in the months of June 2009 (`2009-06`) and July 2009 (`2009-07`).
7.41 +
7.42 +== See Also ==
7.43 +
7.44 + * HelpOnEventAggregator - a macro producing event calendars and listings