1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - EventAggregatorNewEvent Action 4 5 @copyright: 2008, 2009, 2010 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 18 Dependencies = ['pages'] 19 20 # Action class and supporting functions. 21 22 class EventAggregatorNewEvent(ActionBase): 23 24 "An event creation dialogue requesting various parameters." 25 26 def _get_selected(self, value, input_value): 27 return input_value is not None and value == input_value and 'selected="selected"' or '' 28 29 def _get_selected_for_list(self, value, input_values): 30 return value in input_values and 'selected="selected"' or '' 31 32 def _get_input(self, form, name, default=None): 33 value = form.get(name, [None])[0] 34 if not value: # true if 0 obtained 35 return default 36 else: 37 return int(value) 38 39 def get_form_html(self, buttons_html): 40 _ = self._ 41 request = self.request 42 form = request.form 43 44 # Handle advanced and basic forms. 45 46 show_advanced = form.get("advanced") and not form.get("basic") 47 48 # Prepare the category list. 49 50 category_list = [] 51 category_pagenames = form.get("category", []) 52 53 for category_name, category_pagename in \ 54 EventAggregatorSupport.getCategoryMapping( 55 EventAggregatorSupport.getCategories(request), 56 request): 57 58 selected = self._get_selected_for_list(category_pagename, category_pagenames) 59 60 # In the advanced view, populate a menu. 61 62 if show_advanced: 63 category_list.append('<option value="%s" %s>%s</option>' % (category_pagename, selected, category_name)) 64 65 # In the basic view, use hidden fields. 66 67 elif selected: 68 category_list.append('<input value="%s" name="category" type="hidden" />' % category_pagename) 69 70 # Prepare the topics list. 71 72 topics = form.get("topics", []) 73 74 if form.get("add-topic"): 75 topics.append("") 76 else: 77 for i in range(0, len(topics)): 78 if form.get("remove-topic-%d" % i): 79 del topics[i] 80 break 81 82 # Initialise hour and minute lists. 83 84 start_hour_list = [] 85 start_hour_list.append('<option value=""></option>') 86 start_minute_list = [] 87 start_minute_list.append('<option value=""></option>') 88 end_hour_list = [] 89 end_hour_list.append('<option value=""></option>') 90 end_minute_list = [] 91 end_minute_list.append('<option value=""></option>') 92 93 start_hour = self._get_input(form, "start-hour") 94 end_hour = self._get_input(form, "end-hour") 95 start_minute = self._get_input(form, "start-minute") 96 end_minute = self._get_input(form, "end-minute") 97 98 # Prepare hour and minute lists, selecting specified values. 99 100 for hour in range(0, 24): 101 selected = self._get_selected(hour, start_hour) 102 start_hour_list.append('<option value="%02d" %s>%02d</option>' % (hour, selected, hour)) 103 selected = self._get_selected(hour, end_hour) 104 end_hour_list.append('<option value="%02d" %s>%02d</option>' % (hour, selected, hour)) 105 106 for minute in range(0, 60): 107 selected = self._get_selected(minute, start_minute) 108 start_minute_list.append('<option value="%02d" %s>%02d</option>' % (minute, selected, minute)) 109 selected = self._get_selected(minute, end_minute) 110 end_minute_list.append('<option value="%02d" %s>%02d</option>' % (minute, selected, minute)) 111 112 # Initialise month lists. 113 114 start_month_list = [] 115 start_month_list.append('<option value=""></option>') 116 end_month_list = [] 117 end_month_list.append('<option value=""></option>') 118 119 start_month = self._get_input(form, "start-month", 0) 120 end_month = self._get_input(form, "end-month", 0) 121 122 # Prepare month lists, selecting specified months. 123 124 for month in range(1, 13): 125 month_label = _(EventAggregatorSupport.getMonthLabel(month)) 126 selected = self._get_selected(month, start_month) 127 start_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label)) 128 selected = self._get_selected(month, end_month) 129 end_month_list.append('<option value="%02d" %s>%s</option>' % (month, selected, month_label)) 130 131 # Permitting configuration of the template name. 132 133 template_default = getattr(request.cfg, "event_aggregator_new_event_template", "EventTemplate") 134 135 d = { 136 "buttons_html" : buttons_html, 137 "category_label" : _("Categories"), 138 "category_list" : "\n".join(category_list), 139 140 "start_month_list" : "\n".join(start_month_list), 141 "start_hour_list" : "\n".join(start_hour_list), 142 "start_minute_list" : "\n".join(start_minute_list), 143 144 "end_month_list" : "\n".join(end_month_list), 145 "end_hour_list" : "\n".join(end_hour_list), 146 "end_minute_list" : "\n".join(end_minute_list), 147 148 "start_label" : _("Start date (day, month, year)"), 149 "start_day_default" : form.get("start-day", [""])[0], 150 "start_year_default" : form.get("start-year", [""])[0] or EventAggregatorSupport.getCurrentYear(), 151 "start_time_label" : _("Start time (hour, minute, second)"), 152 "start_second_default" : form.get("start-second", [""])[0], 153 154 "end_label" : _("End date (day, month, year) - if different"), 155 "end_day_default" : form.get("end-day", [""])[0], 156 "end_year_default" : form.get("end-year", [""])[0], 157 "end_time_label" : _("End time (hour, minute, second)"), 158 "end_second_default" : form.get("end-second", [""])[0], 159 160 "title_label" : _("Event title/summary"), 161 "title_default" : form.get("title", [""])[0], 162 "description_label" : _("Event description"), 163 "description_default" : form.get("description", [""])[0], 164 "location_label" : _("Event location"), 165 "location_default" : form.get("location", [""])[0], 166 "link_label" : _("Event URL"), 167 "link_default" : form.get("link", [""])[0], 168 169 "topics_label" : _("Topics"), 170 "add_topic_label" : _("Add topic"), 171 "remove_topic_label" : _("Remove topic"), 172 173 "template_label" : _("Event template"), 174 "template_default" : form.get("template", [""])[0] or template_default, 175 "parent_label" : _("Parent page"), 176 "parent_default" : form.get("parent", [""])[0], 177 178 "advanced_label" : _("Show advanced options"), 179 "basic_label" : _("Show basic options"), 180 } 181 182 # Prepare the output HTML. 183 184 html = ''' 185 <table> 186 <tr> 187 <td class="label"><label>%(title_label)s</label></td> 188 <td> 189 <input name="title" type="text" size="40" value="%(title_default)s" /> 190 </td> 191 </tr> 192 <tr> 193 <td class="label"><label>%(start_label)s</label></td> 194 <td> 195 <input name="start-day" type="text" value="%(start_day_default)s" size="2" /> 196 <select name="start-month"> 197 %(start_month_list)s 198 </select> 199 <input name="start-year" type="text" value="%(start_year_default)s" size="4" /> 200 </td> 201 </tr> 202 <tr> 203 <td class="label"><label>%(start_time_label)s</label></td> 204 <td> 205 <select name="start-hour"> 206 %(start_hour_list)s 207 </select> 208 <select name="start-minute"> 209 %(start_minute_list)s 210 </select> 211 <input name="start-second" type="text" value="%(start_second_default)s" size="2" /> 212 </td> 213 </tr> 214 <tr> 215 <td class="label"><label>%(end_label)s</label></td> 216 <td> 217 <input name="end-day" type="text" value="%(end_day_default)s" size="2" /> 218 <select name="end-month"> 219 %(end_month_list)s 220 </select> 221 <input name="end-year" type="text" value="%(end_year_default)s" size="4" /> 222 </td> 223 </tr> 224 <tr> 225 <td class="label"><label>%(end_time_label)s</label></td> 226 <td> 227 <select name="end-hour"> 228 %(end_hour_list)s 229 </select> 230 <select name="end-minute"> 231 %(end_minute_list)s 232 </select> 233 <input name="end-second" type="text" value="%(end_second_default)s" size="2" /> 234 </td> 235 </tr> 236 <tr> 237 <td class="label"><label>%(description_label)s</label></td> 238 <td> 239 <input name="description" type="text" size="40" value="%(description_default)s" /> 240 </td> 241 </tr> 242 <tr> 243 <td class="label"><label>%(location_label)s</label></td> 244 <td> 245 <input name="location" type="text" size="40" value="%(location_default)s" /> 246 </td> 247 </tr> 248 <tr> 249 <tr> 250 <td class="label"><label>%(link_label)s</label></td> 251 <td> 252 <input name="link" type="text" size="40" value="%(link_default)s" /> 253 </td> 254 </tr>''' % d 255 256 # Topics. 257 258 for i, topic in enumerate(topics): 259 d["topic"] = topic 260 d["topic_number"] = i 261 html += ''' 262 <tr> 263 <td class="label"><label>%(topics_label)s</label></td> 264 <td> 265 <input name="topics" type="text" size="20" value="%(topic)s" /> 266 <input name="remove-topic-%(topic_number)s" type="submit" value="%(remove_topic_label)s" /> 267 </td> 268 </tr>''' % d 269 270 html += ''' 271 <tr> 272 <td></td> 273 <td> 274 <input name="add-topic" type="submit" value="%(add_topic_label)s" /> 275 </td> 276 </tr>''' % d 277 278 # Advanced options. 279 280 if show_advanced: 281 html += ''' 282 <tr> 283 <td></td> 284 <td> 285 <input name="basic" type="submit" value="%(basic_label)s" /> 286 <input name="advanced" type="hidden" value="true" /> 287 </td> 288 </tr> 289 <tr> 290 <td class="label"><label>%(category_label)s</label></td> 291 <td class="content"> 292 <select multiple="multiple" name="category"> 293 %(category_list)s 294 </select> 295 </td> 296 </tr> 297 <tr> 298 <td class="label"><label>%(template_label)s</label></td> 299 <td> 300 <input name="template" type="text" size="40" value="%(template_default)s" /> 301 </td> 302 </tr> 303 <tr> 304 <td class="label"><label>%(parent_label)s</label></td> 305 <td> 306 <input name="parent" type="text" size="40" value="%(parent_default)s" /> 307 </td> 308 </tr> 309 <tr> 310 <td></td> 311 <td class="buttons"> 312 %(buttons_html)s 313 </td> 314 </tr> 315 </table>''' % d 316 else: 317 html += ''' 318 <tr> 319 <td></td> 320 <td> 321 <input name="advanced" type="submit" value="%(advanced_label)s" /> 322 %(category_list)s 323 <input name="parent" type="hidden" value="%(parent_default)s" /> 324 <input name="template" type="hidden" value="%(template_default)s" /> 325 </td> 326 </tr> 327 <tr> 328 <td></td> 329 <td class="buttons"> 330 %(buttons_html)s 331 </td> 332 </tr> 333 </table>''' % d 334 335 return html 336 337 def do_action(self): 338 339 "Create the new event." 340 341 _ = self._ 342 form = self.request.form 343 344 # If no title exists in the request, an error message is returned. 345 346 title = form.get("title", [None])[0] 347 template = form.get("template", [None])[0] 348 349 if not title: 350 return 0, _("No event title specified.") 351 352 if not template: 353 return 0, _("No page template specified.") 354 355 return self.create_event(self.request) 356 357 def render_success(self, msg, msgtype=None): 358 359 """ 360 Render neither 'msg' nor 'msgtype' since redirection should occur 361 instead. 362 NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. 363 """ 364 365 pass 366 367 def create_event(self, request): 368 369 "Create an event page using the 'request'." 370 371 _ = request.getText 372 form = request.form 373 374 category_pagenames = form.get("category", []) 375 description = form.get("description", [None])[0] 376 location = form.get("location", [None])[0] 377 link = form.get("link", [None])[0] 378 topics = form.get("topics", []) 379 380 start_zone = form.get("start-zone", [None])[0] 381 end_zone = form.get("end-zone", [None])[0] 382 383 # Validate certain fields. 384 385 try: 386 title = form["title"][0] 387 template = form["template"][0] 388 parent = form["parent"][0] 389 except (KeyError, IndexError): 390 return 0, _("Event title or template missing.") 391 392 try: 393 start_day = self._get_input(form, "start-day", 0) 394 start_month = self._get_input(form, "start-month", 0) 395 start_year = self._get_input(form, "start-year", 0) 396 end_day = self._get_input(form, "end-day", start_day) 397 end_month = self._get_input(form, "end-month", start_month) 398 end_year = self._get_input(form, "end-year", start_year) 399 400 except (TypeError, ValueError): 401 return 0, _("Days and years must be numbers yielding a valid date!") 402 403 try: 404 start_hour = self._get_input(form, "start-hour") 405 start_minute = self._get_input(form, "start-minute") 406 start_second = self._get_input(form, "start-second") 407 408 end_hour = self._get_input(form, "end-hour") 409 end_minute = self._get_input(form, "end-minute") 410 end_second = self._get_input(form, "end-second") 411 412 except (TypeError, ValueError): 413 return 0, _("Hours, minutes and seconds must be numbers yielding a valid time!") 414 415 start_date = EventAggregatorSupport.DateTime( 416 (start_year, start_month, start_day, start_hour, start_minute, start_second, start_zone) 417 ) 418 start_date.constrain() 419 420 end_date = EventAggregatorSupport.DateTime( 421 (end_year, end_month, end_day, end_hour, end_minute, end_second, end_zone) 422 ) 423 end_date.constrain() 424 425 # An elementary date ordering check. 426 427 if (start_date.as_date() != end_date.as_date() or start_date.has_time() and end_date.has_time()) and start_date > end_date: 428 start_date, end_date = end_date, start_date 429 430 event_details = { 431 "start" : str(start_date), "end" : str(end_date), 432 "title" : title, "summary" : title, 433 "description" : description, "location" : location, "link" : link, 434 "topics" : [topic for topic in topics if topic] 435 } 436 437 # Copy the template. 438 439 template_page = PageEditor(request, template) 440 441 if not template_page.exists(): 442 return 0, _("Event template not available.") 443 444 # Use any parent page information. 445 446 full_title = EventAggregatorSupport.getFullPageName(parent, title) 447 448 # Load the new page and replace the event details in the body. 449 450 new_page = PageEditor(request, full_title) 451 452 if new_page.exists(): 453 return 0, _("The specified page already exists. Please choose another name.") 454 455 # Complete the new page. 456 457 EventAggregatorSupport.fillEventPageFromTemplate(template_page, 458 new_page, event_details, category_pagenames) 459 460 # Redirect and return success. 461 462 query = {'action' : 'edit'} 463 request.http_redirect(new_page.url(request, query)) 464 return 1, None 465 466 # Action function. 467 468 def execute(pagename, request): 469 EventAggregatorNewEvent(pagename, request).render() 470 471 # vim: tabstop=4 expandtab shiftwidth=4