1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/actions/EventAggregatorNewEvent.py Sat Jun 06 02:17:51 2009 +0200
1.3 @@ -0,0 +1,236 @@
1.4 +# -*- coding: iso-8859-1 -*-
1.5 +"""
1.6 + MoinMoin - EventAggregatorNewEvent Action
1.7 +
1.8 + @copyright: 2008, 2009 by Paul Boddie <paul@boddie.org.uk>
1.9 + @copyright: 2000-2004 Juergen Hermann <jh@web.de>,
1.10 + 2003-2008 MoinMoin:ThomasWaldmann,
1.11 + 2004-2006 MoinMoin:AlexanderSchremmer,
1.12 + 2007 MoinMoin:ReimarBauer.
1.13 + @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.14 +"""
1.15 +
1.16 +from MoinMoin.action import ActionBase
1.17 +from MoinMoin.Page import Page
1.18 +from MoinMoin.PageEditor import PageEditor
1.19 +import EventAggregatorSupport
1.20 +import calendar
1.21 +import re
1.22 +
1.23 +Dependencies = ['pages']
1.24 +
1.25 +# Action class and supporting functions.
1.26 +
1.27 +class EventAggregatorNewEvent(ActionBase):
1.28 +
1.29 + "An event creation dialogue requesting various parameters."
1.30 +
1.31 + # NOTE: These patterns, used to replace text in the template, must
1.32 + # NOTE: correspond with the template and the recognised labels found in
1.33 + # NOTE: EventAggregatorSummary.getEventDetails.
1.34 +
1.35 + start_pattern = re.compile("(?<= start:: ).*?(?P<date>yyyy-mm-dd)")
1.36 + end_pattern = re.compile("(?<= end:: ).*?(?P<date>yyyy-mm-dd)")
1.37 + topics_pattern = re.compile(r"(?<= categories:: )\s*(.*?)$|(?<= topics:: )\s*(.*?)$", re.MULTILINE | re.UNICODE)
1.38 + category_pattern = re.compile(r"^\s*((Category\S+)(\s+Category\S+)*)\s*$", re.MULTILINE | re.UNICODE)
1.39 +
1.40 + def _get_selected(self, month, input_month):
1.41 + return (("%02d" % month) == input_month) and 'selected="selected"' or ''
1.42 +
1.43 + def get_form_html(self, buttons_html):
1.44 + _ = self._
1.45 + request = self.request
1.46 + form = request.form
1.47 +
1.48 + category_list = []
1.49 +
1.50 + for category_name, category_pagename in \
1.51 + EventAggregatorSupport.getCategoryMapping(
1.52 + EventAggregatorSupport.getCategories(request),
1.53 + request):
1.54 +
1.55 + category_list.append('<option value="%s">%s</option>' % (category_pagename, category_name))
1.56 +
1.57 + # Initialise month lists.
1.58 +
1.59 + start_month_list = []
1.60 + start_month_list.append('<option value=""></option>')
1.61 + end_month_list = []
1.62 + end_month_list.append('<option value=""></option>')
1.63 +
1.64 + start_month = form.get("start-month", [None])[0]
1.65 + end_month = form.get("end-month", [None])[0]
1.66 +
1.67 + # Prepare month lists, selecting specified months.
1.68 +
1.69 + for month in range(1, 13):
1.70 + month_label = _(EventAggregatorSupport.getMonthLabel(month))
1.71 + selected = self._get_selected(month, start_month)
1.72 + start_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label))
1.73 + selected = self._get_selected(month, end_month)
1.74 + end_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label))
1.75 +
1.76 + d = {
1.77 + "buttons_html" : buttons_html,
1.78 + "category_label" : _("Categories"),
1.79 + "category_list" : "\n".join(category_list),
1.80 + "start_month_list" : "\n".join(start_month_list),
1.81 + "end_month_list" : "\n".join(end_month_list),
1.82 + "start_label" : _("Start date (day, month, year)"),
1.83 + "start_day_default" : form.get("start-day", [""])[0],
1.84 + "start_year_default" : form.get("start-year", [""])[0],
1.85 + "end_label" : _("End date (day, month, year)"),
1.86 + "end_day_default" : form.get("end-day", [""])[0],
1.87 + "end_year_default" : form.get("end-year", [""])[0],
1.88 + "title_label" : _("Event title/summary"),
1.89 + }
1.90 +
1.91 + return '''
1.92 +<table>
1.93 + <tr>
1.94 + <td class="label"><label>%(title_label)s</label></td>
1.95 + <td>
1.96 + <input name="title" type="text" size="40" />
1.97 + <tr>
1.98 + <td class="label"><label>%(category_label)s</label></td>
1.99 + <td class="content">
1.100 + <select multiple="multiple" name="category">
1.101 + %(category_list)s
1.102 + </select>
1.103 + </td>
1.104 + </tr>
1.105 + <tr>
1.106 + <td class="label"><label>%(start_label)s</label></td>
1.107 + <td>
1.108 + <input name="start-day" type="text" value="%(start_day_default)s" size="2" />
1.109 + <select name="start-month">
1.110 + %(start_month_list)s
1.111 + </select>
1.112 + <input name="start-year" type="text" value="%(start_year_default)s" size="4" />
1.113 + </td>
1.114 + </tr>
1.115 + <tr>
1.116 + <td class="label"><label>%(end_label)s</label></td>
1.117 + <td>
1.118 + <input name="end-day" type="text" value="%(end_day_default)s" size="2" />
1.119 + <select name="end-month">
1.120 + %(end_month_list)s
1.121 + </select>
1.122 + <input name="end-year" type="text" value="%(end_year_default)s" size="4" />
1.123 + </td>
1.124 + </tr>
1.125 + <tr>
1.126 + <td></td>
1.127 + <td class="buttons">
1.128 + %(buttons_html)s
1.129 + </td>
1.130 + </tr>
1.131 +</table>
1.132 +''' % d
1.133 +
1.134 + def do_action(self):
1.135 +
1.136 + "Create the new event."
1.137 +
1.138 + _ = self._
1.139 + form = self.request.form
1.140 +
1.141 + # If no title exists in the request, an error message is returned.
1.142 +
1.143 + title = form.get("title", [None])[0]
1.144 +
1.145 + if not title:
1.146 + return 0, _("No event title specified.")
1.147 +
1.148 + return self.create_event(self.request)
1.149 +
1.150 + def render_success(self, msg, msgtype=None):
1.151 +
1.152 + """
1.153 + Render neither 'msg' nor 'msgtype' since redirection should occur
1.154 + instead.
1.155 + NOTE: msgtype is optional because MoinMoin 1.5.x does not support it.
1.156 + """
1.157 +
1.158 + pass
1.159 +
1.160 + def create_event(self, request):
1.161 +
1.162 + "Create an event page using the 'request'."
1.163 +
1.164 + _ = request.getText
1.165 +
1.166 + category_names = request.form.get("category", [])
1.167 + title = request.form.get("title", [None])[0]
1.168 +
1.169 + try:
1.170 + start_day = int(request.form.get("start-day", [None])[0] or 0)
1.171 + start_month = int(request.form.get("start-month", [None])[0] or 0)
1.172 + start_year = int(request.form.get("start-year", [None])[0] or 0)
1.173 + end_day = int(request.form.get("end-day", [None])[0] or start_day)
1.174 + end_month = int(request.form.get("end-month", [None])[0] or start_month)
1.175 + end_year = int(request.form.get("end-year", [None])[0] or start_year)
1.176 +
1.177 + start_year, start_month, start_day = self.constrain_date(start_year, start_month, start_day)
1.178 + end_year, end_month, end_day = self.constrain_date(end_year, end_month, end_day)
1.179 +
1.180 + except ValueError:
1.181 + return 0, _("Days and years must be numbers yielding a valid date!")
1.182 +
1.183 + start_date = self.make_date_string(start_year, start_month, start_day)
1.184 + end_date = self.make_date_string(end_year, end_month, end_day)
1.185 +
1.186 + # Copy the template.
1.187 + # Permitting configuration of the template name.
1.188 +
1.189 + page = PageEditor(request, getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate"))
1.190 + body = page.get_raw_body()
1.191 +
1.192 + # Load the new page and replace the placeholders.
1.193 +
1.194 + new_page = PageEditor(request, title)
1.195 +
1.196 + if new_page.exists():
1.197 + return 0, _("The specified page already exists. Please choose another name.")
1.198 +
1.199 + # NOTE: The placeholders must match the template.
1.200 +
1.201 + body = self.replace_placeholder(body, self.start_pattern, start_date, 1)
1.202 + body = self.replace_placeholder(body, self.end_pattern, end_date, 1)
1.203 + body = self.replace_placeholder(body, self.category_pattern, " ".join(category_names))
1.204 +
1.205 + new_page.saveText(body, 0)
1.206 +
1.207 + # Redirect and return success.
1.208 +
1.209 + query = {'action' : 'edit', 'backto' : self.pagename}
1.210 + request.http_redirect(new_page.url(request, query))
1.211 + return 1, None
1.212 +
1.213 + def replace_placeholder(self, body, pattern, value, lower=0):
1.214 + match = pattern.search(lower and body.lower() or body)
1.215 + if match:
1.216 + start, end = match.span()
1.217 + return body[:start] + value + body[end:]
1.218 + else:
1.219 + return body
1.220 +
1.221 + def make_date_string(self, year, month, day):
1.222 + return "%s-%s-%s" % (
1.223 + year and ("%04d" % year) or "YYYY",
1.224 + month and ("%02d" % month) or "MM",
1.225 + day and ("%02d" % day) or "DD"
1.226 + )
1.227 +
1.228 + def constrain_date(self, year, month, day):
1.229 + if year and month and day:
1.230 + wd, last_day = calendar.monthrange(year, month)
1.231 + day = max(min(day, last_day), 1)
1.232 + return year, month, day
1.233 +
1.234 +# Action function.
1.235 +
1.236 +def execute(pagename, request):
1.237 + EventAggregatorNewEvent(pagename, request).render()
1.238 +
1.239 +# vim: tabstop=4 expandtab shiftwidth=4