1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - EventAggregatorNewEvent Action 4 5 @copyright: 2008, 2009 by Paul Boddie <paul@boddie.org.uk> 6 @copyright: 2000-2004 Juergen Hermann <jh@web.de>, 7 2003-2008 MoinMoin:ThomasWaldmann, 8 2004-2006 MoinMoin:AlexanderSchremmer, 9 2007 MoinMoin:ReimarBauer. 10 @license: GNU GPL (v2 or later), see COPYING.txt for details. 11 """ 12 13 from MoinMoin.action import ActionBase 14 from MoinMoin.Page import Page 15 from MoinMoin.PageEditor import PageEditor 16 import EventAggregatorSupport 17 import calendar 18 import re 19 20 Dependencies = ['pages'] 21 22 # Action class and supporting functions. 23 24 class EventAggregatorNewEvent(ActionBase): 25 26 "An event creation dialogue requesting various parameters." 27 28 # NOTE: These patterns, used to replace text in the template, must 29 # NOTE: correspond with the template and the recognised labels found in 30 # NOTE: EventAggregatorSummary.getEventDetails. 31 32 start_pattern = re.compile("(?<= start:: ).*?(?P<date>yyyy-mm-dd)") 33 end_pattern = re.compile("(?<= end:: ).*?(?P<date>yyyy-mm-dd)") 34 topics_pattern = re.compile(r"(?<= categories:: )\s*(.*?)$|(?<= topics:: )\s*(.*?)$", re.MULTILINE | re.UNICODE) 35 category_pattern = re.compile(r"^\s*((Category\S+)(\s+Category\S+)*)\s*$", re.MULTILINE | re.UNICODE) 36 37 def _get_selected(self, month, input_month): 38 return (("%02d" % month) == input_month) and 'selected="selected"' or '' 39 40 def get_form_html(self, buttons_html): 41 _ = self._ 42 request = self.request 43 form = request.form 44 45 category_list = [] 46 47 for category_name, category_pagename in \ 48 EventAggregatorSupport.getCategoryMapping( 49 EventAggregatorSupport.getCategories(request), 50 request): 51 52 category_list.append('<option value="%s">%s</option>' % (category_pagename, category_name)) 53 54 # Initialise month lists. 55 56 start_month_list = [] 57 start_month_list.append('<option value=""></option>') 58 end_month_list = [] 59 end_month_list.append('<option value=""></option>') 60 61 start_month = form.get("start-month", [None])[0] 62 end_month = form.get("end-month", [None])[0] 63 64 # Prepare month lists, selecting specified months. 65 66 for month in range(1, 13): 67 month_label = _(EventAggregatorSupport.getMonthLabel(month)) 68 selected = self._get_selected(month, start_month) 69 start_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label)) 70 selected = self._get_selected(month, end_month) 71 end_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label)) 72 73 d = { 74 "buttons_html" : buttons_html, 75 "category_label" : _("Categories"), 76 "category_list" : "\n".join(category_list), 77 "start_month_list" : "\n".join(start_month_list), 78 "end_month_list" : "\n".join(end_month_list), 79 "start_label" : _("Start date (day, month, year)"), 80 "start_day_default" : form.get("start-day", [""])[0], 81 "start_year_default" : form.get("start-year", [""])[0], 82 "end_label" : _("End date (day, month, year)"), 83 "end_day_default" : form.get("end-day", [""])[0], 84 "end_year_default" : form.get("end-year", [""])[0], 85 "title_label" : _("Event title/summary"), 86 } 87 88 return ''' 89 <table> 90 <tr> 91 <td class="label"><label>%(title_label)s</label></td> 92 <td> 93 <input name="title" type="text" size="40" /> 94 <tr> 95 <td class="label"><label>%(category_label)s</label></td> 96 <td class="content"> 97 <select multiple="multiple" name="category"> 98 %(category_list)s 99 </select> 100 </td> 101 </tr> 102 <tr> 103 <td class="label"><label>%(start_label)s</label></td> 104 <td> 105 <input name="start-day" type="text" value="%(start_day_default)s" size="2" /> 106 <select name="start-month"> 107 %(start_month_list)s 108 </select> 109 <input name="start-year" type="text" value="%(start_year_default)s" size="4" /> 110 </td> 111 </tr> 112 <tr> 113 <td class="label"><label>%(end_label)s</label></td> 114 <td> 115 <input name="end-day" type="text" value="%(end_day_default)s" size="2" /> 116 <select name="end-month"> 117 %(end_month_list)s 118 </select> 119 <input name="end-year" type="text" value="%(end_year_default)s" size="4" /> 120 </td> 121 </tr> 122 <tr> 123 <td></td> 124 <td class="buttons"> 125 %(buttons_html)s 126 </td> 127 </tr> 128 </table> 129 ''' % d 130 131 def do_action(self): 132 133 "Create the new event." 134 135 _ = self._ 136 form = self.request.form 137 138 # If no title exists in the request, an error message is returned. 139 140 title = form.get("title", [None])[0] 141 142 if not title: 143 return 0, _("No event title specified.") 144 145 return self.create_event(self.request) 146 147 def render_success(self, msg, msgtype=None): 148 149 """ 150 Render neither 'msg' nor 'msgtype' since redirection should occur 151 instead. 152 NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. 153 """ 154 155 pass 156 157 def create_event(self, request): 158 159 "Create an event page using the 'request'." 160 161 _ = request.getText 162 163 category_names = request.form.get("category", []) 164 title = request.form.get("title", [None])[0] 165 166 try: 167 start_day = int(request.form.get("start-day", [None])[0] or 0) 168 start_month = int(request.form.get("start-month", [None])[0] or 0) 169 start_year = int(request.form.get("start-year", [None])[0] or 0) 170 end_day = int(request.form.get("end-day", [None])[0] or start_day) 171 end_month = int(request.form.get("end-month", [None])[0] or start_month) 172 end_year = int(request.form.get("end-year", [None])[0] or start_year) 173 174 start_year, start_month, start_day = self.constrain_date(start_year, start_month, start_day) 175 end_year, end_month, end_day = self.constrain_date(end_year, end_month, end_day) 176 177 except ValueError: 178 return 0, _("Days and years must be numbers yielding a valid date!") 179 180 start_date = self.make_date_string(start_year, start_month, start_day) 181 end_date = self.make_date_string(end_year, end_month, end_day) 182 183 # Copy the template. 184 # Permitting configuration of the template name. 185 186 page = PageEditor(request, getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate")) 187 body = page.get_raw_body() 188 189 # Load the new page and replace the placeholders. 190 191 new_page = PageEditor(request, title) 192 193 if new_page.exists(): 194 return 0, _("The specified page already exists. Please choose another name.") 195 196 # NOTE: The placeholders must match the template. 197 198 body = self.replace_placeholder(body, self.start_pattern, start_date, 1) 199 body = self.replace_placeholder(body, self.end_pattern, end_date, 1) 200 body = self.replace_placeholder(body, self.category_pattern, " ".join(category_names)) 201 202 new_page.saveText(body, 0) 203 204 # Redirect and return success. 205 206 query = {'action' : 'edit', 'backto' : self.pagename} 207 request.http_redirect(new_page.url(request, query)) 208 return 1, None 209 210 def replace_placeholder(self, body, pattern, value, lower=0): 211 match = pattern.search(lower and body.lower() or body) 212 if match: 213 start, end = match.span() 214 return body[:start] + value + body[end:] 215 else: 216 return body 217 218 def make_date_string(self, year, month, day): 219 return "%s-%s-%s" % ( 220 year and ("%04d" % year) or "YYYY", 221 month and ("%02d" % month) or "MM", 222 day and ("%02d" % day) or "DD" 223 ) 224 225 def constrain_date(self, year, month, day): 226 if year and month and day: 227 wd, last_day = calendar.monthrange(year, month) 228 day = max(min(day, last_day), 1) 229 return year, month, day 230 231 # Action function. 232 233 def execute(pagename, request): 234 EventAggregatorNewEvent(pagename, request).render() 235 236 # vim: tabstop=4 expandtab shiftwidth=4