1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - EventAggregatorSummary Action 4 5 @copyright: 2008, 2009, 2010, 2011, 2012 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 2009 Cristian Rigamonti <rigamonti@fsfeurope.org> 11 @license: GNU GPL (v2 or later), see COPYING.txt for details. 12 """ 13 14 from MoinMoin.action import ActionBase 15 from MoinMoin import config 16 from MoinMoin.Page import Page 17 from MoinMoin import wikiutil 18 from EventAggregatorSupport import * 19 20 Dependencies = ['pages'] 21 22 # Action class and supporting functions. 23 24 class EventAggregatorSummary(ActionBase, ActionSupport): 25 26 "A summary dialogue requesting various parameters." 27 28 def get_form_html(self, buttons_html): 29 _ = self._ 30 request = self.request 31 form = self.get_form() 32 33 resolution = form.get("resolution", ["month"])[0] 34 35 category_list = [] 36 category_pagenames = form.get("category", []) 37 38 for category_name, category_pagename in getCategoryMapping(getCategories(request), request): 39 40 selected = self._get_selected_for_list(category_pagename, category_pagenames) 41 42 category_list.append('<option value="%s" %s>%s</option>' % ( 43 escattr(category_pagename), selected, escape(category_name))) 44 45 sources_list = [] 46 sources = form.get("source", []) 47 source_names = (getAllEventSources(request) or {}).keys() 48 source_names.sort() 49 50 for source_name in source_names: 51 52 selected = self._get_selected_for_list(source_name, sources) 53 54 sources_list.append('<option value="%s" %s>%s</option>' % ( 55 escattr(source_name), selected, escape(source_name))) 56 57 # Initialise month lists and defaults. 58 59 start_month_list, end_month_list = self.get_month_lists() 60 start_day_default, end_day_default = self.get_day_defaults() 61 start_year_default, end_year_default = self.get_year_defaults() 62 63 # Criteria instead of months and years. 64 65 start_criteria_default = form.get("start", [""])[0] 66 end_criteria_default = form.get("end", [""])[0] 67 68 if resolution == "date": 69 get_parameter = getParameterDate 70 get_label = getFullDateLabel 71 else: 72 get_parameter = getParameterMonth 73 get_label = getFullMonthLabel 74 75 start_criteria_evaluated = get_parameter(start_criteria_default) 76 end_criteria_evaluated = get_parameter(end_criteria_default) 77 78 start_criteria_evaluated = get_label(request, start_criteria_evaluated) 79 end_criteria_evaluated = get_label(request, end_criteria_evaluated) 80 81 # Descriptions. 82 83 descriptions = form.get("descriptions", [None])[0] 84 85 descriptions_list = [ 86 '<option value="%s" %s>%s</option>' % ("page", self._get_selected("page", descriptions), escape(_("page"))), 87 '<option value="%s" %s>%s</option>' % ("comment", self._get_selected("comment", descriptions), escape(_("comment"))) 88 ] 89 90 # Format. 91 92 format = form.get("format", [None])[0] 93 94 format_list = [ 95 '<option value="%s" %s>%s</option>' % ("iCalendar", self._get_selected("iCalendar", format), escape(_("iCalendar"))), 96 '<option value="%s" %s>%s</option>' % ("RSS", self._get_selected("RSS", format), escape(_("RSS 2.0"))) 97 ] 98 99 right_arrow = unicode('\xe2\x86\x92', "utf-8") 100 101 d = { 102 "buttons_html" : buttons_html, 103 "category_label" : escape(_("Categories")), 104 "category_list" : "\n".join(category_list), 105 "sources_label" : escape(_("Sources")), 106 "sources_list" : "\n".join(sources_list), 107 "search_label" : escape(_("Search pattern")), 108 "search_default" : escattr(form.get("search", [""])[0]), 109 "start_month_list" : "\n".join(start_month_list), 110 "start_label" : escape(_("Start day (optional), month and year")), 111 "start_day_default" : escattr(start_day_default), 112 "start_year_default" : escattr(start_year_default), 113 "start_criteria_label" : escape(_("or special criteria")), 114 "start_criteria_default": escattr(start_criteria_default), 115 "start_eval_label" : escattr(right_arrow), 116 "start_criteria_eval" : escape(start_criteria_evaluated), 117 "end_month_list" : "\n".join(end_month_list), 118 "end_label" : escape(_("End day (optional), month and year")), 119 "end_day_default" : escattr(end_day_default), 120 "end_year_default" : escattr(end_year_default), 121 "end_criteria_label" : escape(_("or special criteria")), 122 "end_criteria_default" : escattr(end_criteria_default), 123 "end_eval_label" : escattr(right_arrow), 124 "end_criteria_eval" : escape(end_criteria_evaluated), 125 "descriptions_label" : escape(_("Use descriptions from...")), 126 "descriptions_list" : "\n".join(descriptions_list), 127 "format_label" : escape(_("Summary format")), 128 "format_list" : "\n".join(format_list), 129 "parent_label" : escape(_("Parent page")), 130 "parent_name" : escattr(form.get("parent", [""])[0]), 131 "resolution" : escattr(resolution), 132 } 133 134 return ''' 135 <input name="resolution" type="hidden" value="%(resolution)s" /> 136 <table> 137 <tr> 138 <td class="label"><label>%(search_label)s</label></td> 139 <td class="content"> 140 <input name="search" type="text" value="%(search_default)s" size="40" /> 141 </td> 142 </tr> 143 <tr> 144 <td class="label"><label>%(category_label)s</label></td> 145 <td class="content"> 146 <select multiple="multiple" name="category"> 147 %(category_list)s 148 </select> 149 </td> 150 </tr> 151 <tr> 152 <td class="label"><label>%(sources_label)s</label></td> 153 <td class="content"> 154 <select multiple="multiple" name="source"> 155 %(sources_list)s 156 </select> 157 </td> 158 </tr> 159 <tr> 160 <td class="label"><label>%(start_label)s</label></td> 161 <td> 162 <input name="start-day" type="text" value="%(start_day_default)s" size="2" /> 163 <select name="start-month"> 164 %(start_month_list)s 165 </select> 166 <input name="start-year" type="text" value="%(start_year_default)s" size="4" /> 167 </td> 168 </tr> 169 <tr> 170 <td class="label"><label>%(start_criteria_label)s</label></td> 171 <td> 172 <input name="start" type="text" value="%(start_criteria_default)s" size="12" /> 173 <input name="start-eval" type="submit" value="%(start_eval_label)s" /> 174 %(start_criteria_eval)s 175 </td> 176 </tr> 177 <tr> 178 <td class="label"><label>%(end_label)s</label></td> 179 <td> 180 <input name="end-day" type="text" value="%(end_day_default)s" size="2" /> 181 <select name="end-month"> 182 %(end_month_list)s 183 </select> 184 <input name="end-year" type="text" value="%(end_year_default)s" size="4" /> 185 </td> 186 </tr> 187 <tr> 188 <td class="label"><label>%(end_criteria_label)s</label></td> 189 <td> 190 <input name="end" type="text" value="%(end_criteria_default)s" size="12" /> 191 <input name="end-eval" type="submit" value="%(end_eval_label)s" /> 192 %(end_criteria_eval)s 193 </td> 194 </tr> 195 <tr> 196 <td class="label"><label>%(descriptions_label)s</label></td> 197 <td class="content"> 198 <select name="descriptions"> 199 %(descriptions_list)s 200 </select> 201 </td> 202 </tr> 203 <tr> 204 <td class="label"><label>%(format_label)s</label></td> 205 <td class="content"> 206 <select name="format"> 207 %(format_list)s 208 </select> 209 </td> 210 </tr> 211 <tr> 212 <td class="label"><label>%(parent_label)s</label></td> 213 <td class="content"> 214 <input name="parent" type="text" size="40" value="%(parent_name)s" /> 215 </td> 216 </tr> 217 <tr> 218 <td></td> 219 <td class="buttons"> 220 %(buttons_html)s 221 </td> 222 </tr> 223 </table> 224 ''' % d 225 226 def do_action(self): 227 228 "Write the iCalendar resource." 229 230 _ = self._ 231 form = self.get_form() 232 233 # If no category names or sources exist in the request, an error message 234 # is returned. 235 236 category_names = form.get("category") 237 sources = form.get("source") 238 search_pattern = form.get("search") 239 240 if not (category_names or sources or search_pattern): 241 return 0, _("No categories, sources or search patterns specified.") 242 243 write_resource(self.request) 244 return 1, None 245 246 def render_success(self, msg, msgtype=None): 247 248 """ 249 Render neither 'msg' nor 'msgtype' since a resource has already been 250 produced. 251 NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. 252 """ 253 254 pass 255 256 def write_resource(request): 257 258 """ 259 For the given 'request', write an iCalendar summary of the event data found 260 in the categories specified via the "category" request parameter, using the 261 "start" and "end" parameters (if specified). Multiple "category" parameters 262 can be specified. 263 """ 264 265 form = get_form(request) 266 267 category_names = form.get("category", []) 268 remote_sources = form.get("source", []) 269 search_pattern = form.get("search", [None])[0] 270 format = form.get("format", ["iCalendar"])[0] 271 descriptions = form.get("descriptions", ["page"])[0] 272 parent = form.get("parent", [""])[0] 273 resolution = form.get("resolution", ["month"])[0] 274 275 # Look first for a single start and end parameter. If that fails to provide 276 # dates, look for separate start and end parameters, either for complete 277 # dates or for years and months. 278 279 if resolution == "date": 280 calendar_start = getFormDate(request, None, "start") 281 calendar_end = getFormDate(request, None, "end") 282 283 if calendar_start is None: 284 calendar_start = getFormDateTriple(request, "start-year", "start-month", "start-day") 285 if calendar_end is None: 286 calendar_end = getFormDateTriple(request, "end-year", "end-month", "end-day") 287 288 elif resolution == "month": 289 calendar_start = getFormMonth(request, None, "start") 290 calendar_end = getFormMonth(request, None, "end") 291 292 if calendar_start is None: 293 calendar_start = getFormMonthPair(request, "start-year", "start-month") 294 if calendar_end is None: 295 calendar_end = getFormMonthPair(request, "end-year", "end-month") 296 297 # Determine the period and get the events involved. 298 299 all_shown_events, first, last = getEventsUsingParameters( 300 category_names, search_pattern, remote_sources, calendar_start, calendar_end, 301 resolution, request) 302 303 latest_timestamp = getLatestEventTimestamp(all_shown_events) 304 305 # Output summary data... 306 307 send_headers = get_send_headers(request) 308 309 # Define headers. 310 311 if format == "iCalendar": 312 headers = ["Content-Type: text/calendar; charset=%s" % config.charset] 313 elif format == "RSS": 314 headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset] 315 316 # Define the last modified time. 317 318 if latest_timestamp is not None: 319 headers.append("Last-Modified: %s" % latest_timestamp.as_HTTP_datetime_string()) 320 321 send_headers(headers) 322 323 # iCalendar output... 324 325 if format == "iCalendar": 326 mimetype = "text/calendar" 327 328 # RSS output... 329 330 elif format == "RSS": 331 mimetype = "application/rss+xml" 332 333 # Catch-all... 334 335 else: 336 mimetype = None 337 338 formatEventsForOutputType(all_shown_events, request, mimetype, parent, descriptions, latest_timestamp) 339 340 # Action function. 341 342 def execute(pagename, request): 343 EventAggregatorSummary(pagename, request).render() 344 345 # vim: tabstop=4 expandtab shiftwidth=4