# HG changeset patch # User Paul Boddie # Date 1244247471 -7200 # Node ID 8337b0b6177d7cc940658aa02ad359f77bef012b # Parent f87374e888a2b1aa15e8bd729c69d61a48260142 Added an action which adds new events, displaying a form for the event parameters, then copies an event template and makes a new page containing substituted values for each of the specified parameters. Added day number links from the HTML produced by the macro in order to invoke the action. diff -r f87374e888a2 -r 8337b0b6177d actions/EventAggregatorNewEvent.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/actions/EventAggregatorNewEvent.py Sat Jun 06 02:17:51 2009 +0200 @@ -0,0 +1,236 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - EventAggregatorNewEvent Action + + @copyright: 2008, 2009 by Paul Boddie + @copyright: 2000-2004 Juergen Hermann , + 2003-2008 MoinMoin:ThomasWaldmann, + 2004-2006 MoinMoin:AlexanderSchremmer, + 2007 MoinMoin:ReimarBauer. + @license: GNU GPL (v2 or later), see COPYING.txt for details. +""" + +from MoinMoin.action import ActionBase +from MoinMoin.Page import Page +from MoinMoin.PageEditor import PageEditor +import EventAggregatorSupport +import calendar +import re + +Dependencies = ['pages'] + +# Action class and supporting functions. + +class EventAggregatorNewEvent(ActionBase): + + "An event creation dialogue requesting various parameters." + + # NOTE: These patterns, used to replace text in the template, must + # NOTE: correspond with the template and the recognised labels found in + # NOTE: EventAggregatorSummary.getEventDetails. + + start_pattern = re.compile("(?<= start:: ).*?(?Pyyyy-mm-dd)") + end_pattern = re.compile("(?<= end:: ).*?(?Pyyyy-mm-dd)") + topics_pattern = re.compile(r"(?<= categories:: )\s*(.*?)$|(?<= topics:: )\s*(.*?)$", re.MULTILINE | re.UNICODE) + category_pattern = re.compile(r"^\s*((Category\S+)(\s+Category\S+)*)\s*$", re.MULTILINE | re.UNICODE) + + def _get_selected(self, month, input_month): + return (("%02d" % month) == input_month) and 'selected="selected"' or '' + + def get_form_html(self, buttons_html): + _ = self._ + request = self.request + form = request.form + + category_list = [] + + for category_name, category_pagename in \ + EventAggregatorSupport.getCategoryMapping( + EventAggregatorSupport.getCategories(request), + request): + + category_list.append('' % (category_pagename, category_name)) + + # Initialise month lists. + + start_month_list = [] + start_month_list.append('') + end_month_list = [] + end_month_list.append('') + + start_month = form.get("start-month", [None])[0] + end_month = form.get("end-month", [None])[0] + + # Prepare month lists, selecting specified months. + + for month in range(1, 13): + month_label = _(EventAggregatorSupport.getMonthLabel(month)) + selected = self._get_selected(month, start_month) + start_month_list.append('' % (month, selected, month_label)) + selected = self._get_selected(month, end_month) + end_month_list.append('' % (month, selected, month_label)) + + d = { + "buttons_html" : buttons_html, + "category_label" : _("Categories"), + "category_list" : "\n".join(category_list), + "start_month_list" : "\n".join(start_month_list), + "end_month_list" : "\n".join(end_month_list), + "start_label" : _("Start date (day, month, year)"), + "start_day_default" : form.get("start-day", [""])[0], + "start_year_default" : form.get("start-year", [""])[0], + "end_label" : _("End date (day, month, year)"), + "end_day_default" : form.get("end-day", [""])[0], + "end_year_default" : form.get("end-year", [""])[0], + "title_label" : _("Event title/summary"), + } + + return ''' + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + +
+ + + +
+ %(buttons_html)s +
+''' % d + + def do_action(self): + + "Create the new event." + + _ = self._ + form = self.request.form + + # If no title exists in the request, an error message is returned. + + title = form.get("title", [None])[0] + + if not title: + return 0, _("No event title specified.") + + return self.create_event(self.request) + + def render_success(self, msg, msgtype=None): + + """ + Render neither 'msg' nor 'msgtype' since redirection should occur + instead. + NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. + """ + + pass + + def create_event(self, request): + + "Create an event page using the 'request'." + + _ = request.getText + + category_names = request.form.get("category", []) + title = request.form.get("title", [None])[0] + + try: + start_day = int(request.form.get("start-day", [None])[0] or 0) + start_month = int(request.form.get("start-month", [None])[0] or 0) + start_year = int(request.form.get("start-year", [None])[0] or 0) + end_day = int(request.form.get("end-day", [None])[0] or start_day) + end_month = int(request.form.get("end-month", [None])[0] or start_month) + end_year = int(request.form.get("end-year", [None])[0] or start_year) + + start_year, start_month, start_day = self.constrain_date(start_year, start_month, start_day) + end_year, end_month, end_day = self.constrain_date(end_year, end_month, end_day) + + except ValueError: + return 0, _("Days and years must be numbers yielding a valid date!") + + start_date = self.make_date_string(start_year, start_month, start_day) + end_date = self.make_date_string(end_year, end_month, end_day) + + # Copy the template. + # Permitting configuration of the template name. + + page = PageEditor(request, getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate")) + body = page.get_raw_body() + + # Load the new page and replace the placeholders. + + new_page = PageEditor(request, title) + + if new_page.exists(): + return 0, _("The specified page already exists. Please choose another name.") + + # NOTE: The placeholders must match the template. + + body = self.replace_placeholder(body, self.start_pattern, start_date, 1) + body = self.replace_placeholder(body, self.end_pattern, end_date, 1) + body = self.replace_placeholder(body, self.category_pattern, " ".join(category_names)) + + new_page.saveText(body, 0) + + # Redirect and return success. + + query = {'action' : 'edit', 'backto' : self.pagename} + request.http_redirect(new_page.url(request, query)) + return 1, None + + def replace_placeholder(self, body, pattern, value, lower=0): + match = pattern.search(lower and body.lower() or body) + if match: + start, end = match.span() + return body[:start] + value + body[end:] + else: + return body + + def make_date_string(self, year, month, day): + return "%s-%s-%s" % ( + year and ("%04d" % year) or "YYYY", + month and ("%02d" % month) or "MM", + day and ("%02d" % day) or "DD" + ) + + def constrain_date(self, year, month, day): + if year and month and day: + wd, last_day = calendar.monthrange(year, month) + day = max(min(day, last_day), 1) + return year, month, day + +# Action function. + +def execute(pagename, request): + EventAggregatorNewEvent(pagename, request).render() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r f87374e888a2 -r 8337b0b6177d actions/EventAggregatorSummary.py --- a/actions/EventAggregatorSummary.py Sun May 17 17:33:11 2009 +0200 +++ b/actions/EventAggregatorSummary.py Sat Jun 06 02:17:51 2009 +0200 @@ -166,9 +166,11 @@ can be specified. """ - category_names = request.form.get("category", []) - format = request.form.get("format", ["iCalendar"])[0] - descriptions = request.form.get("descriptions", ["page"])[0] + form = request.form + + category_names = form.get("category", []) + format = form.get("format", ["iCalendar"])[0] + descriptions = form.get("descriptions", ["page"])[0] # Otherwise, produce an iCalendar resource. @@ -177,8 +179,6 @@ # Look for separate start and end years and months. - form = request.form - if calendar_start is None: calendar_start = EventAggregatorSupport.getFormMonthPair(request, "start-year", "start-month") diff -r f87374e888a2 -r 8337b0b6177d css/event-aggregator.css --- a/css/event-aggregator.css Sun May 17 17:33:11 2009 +0200 +++ b/css/event-aggregator.css Sat Jun 06 02:17:51 2009 +0200 @@ -101,6 +101,12 @@ padding: 0.25em; } +.event-day-number a:link, +.event-day-number a:hover, +.event-day-number a:visited { + color: inherit !important; +} + /* Day content. */ .event-day-content { diff -r f87374e888a2 -r 8337b0b6177d macros/EventAggregator.py --- a/macros/EventAggregator.py Sun May 17 17:33:11 2009 +0200 +++ b/macros/EventAggregator.py Sat Jun 06 02:17:51 2009 +0200 @@ -358,9 +358,16 @@ else: output.append(fmt.table_cell(on=1, attrs={"class" : "event-day-heading event-day-empty", "colspan" : "3"})) + # Make a link to a new event action. + + new_event_link = "action=EventAggregatorNewEvent&start-day=%02d&start-month=%02d&start-year=%04d" % ( + day, month, year) + + # Output the day number. + output.append(fmt.div(on=1)) output.append(fmt.span(on=1, css_class="event-day-number")) - output.append(fmt.text(unicode(day))) + output.append(linkToPage(request, page, unicode(day), new_event_link)) output.append(fmt.span(on=0)) output.append(fmt.div(on=0))