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 "start_month_list" : "\n".join(start_month_list), 108 "start_label" : escape(_("Start day (optional), month and year")), 109 "start_day_default" : escattr(start_day_default), 110 "start_year_default" : escattr(start_year_default), 111 "start_criteria_label" : escape(_("or special criteria")), 112 "start_criteria_default": escattr(start_criteria_default), 113 "start_eval_label" : escattr(right_arrow), 114 "start_criteria_eval" : escape(start_criteria_evaluated), 115 "end_month_list" : "\n".join(end_month_list), 116 "end_label" : escape(_("End day (optional), month and year")), 117 "end_day_default" : escattr(end_day_default), 118 "end_year_default" : escattr(end_year_default), 119 "end_criteria_label" : escape(_("or special criteria")), 120 "end_criteria_default" : escattr(end_criteria_default), 121 "end_eval_label" : escattr(right_arrow), 122 "end_criteria_eval" : escape(end_criteria_evaluated), 123 "descriptions_label" : escape(_("Use descriptions from...")), 124 "descriptions_list" : "\n".join(descriptions_list), 125 "format_label" : escape(_("Summary format")), 126 "format_list" : "\n".join(format_list), 127 "parent_label" : escape(_("Parent page")), 128 "parent_name" : escattr(form.get("parent", [""])[0]), 129 "resolution" : escattr(resolution), 130 } 131 132 return ''' 133 <input name="resolution" type="hidden" value="%(resolution)s" /> 134 <table> 135 <tr> 136 <td class="label"><label>%(category_label)s</label></td> 137 <td class="content"> 138 <select multiple="multiple" name="category"> 139 %(category_list)s 140 </select> 141 </td> 142 </tr> 143 <tr> 144 <td class="label"><label>%(sources_label)s</label></td> 145 <td class="content"> 146 <select multiple="multiple" name="source"> 147 %(sources_list)s 148 </select> 149 </td> 150 </tr> 151 <tr> 152 <td class="label"><label>%(start_label)s</label></td> 153 <td> 154 <input name="start-day" type="text" value="%(start_day_default)s" size="2" /> 155 <select name="start-month"> 156 %(start_month_list)s 157 </select> 158 <input name="start-year" type="text" value="%(start_year_default)s" size="4" /> 159 </td> 160 </tr> 161 <tr> 162 <td class="label"><label>%(start_criteria_label)s</label></td> 163 <td> 164 <input name="start" type="text" value="%(start_criteria_default)s" size="12" /> 165 <input name="start-eval" type="submit" value="%(start_eval_label)s" /> 166 %(start_criteria_eval)s 167 </td> 168 </tr> 169 <tr> 170 <td class="label"><label>%(end_label)s</label></td> 171 <td> 172 <input name="end-day" type="text" value="%(end_day_default)s" size="2" /> 173 <select name="end-month"> 174 %(end_month_list)s 175 </select> 176 <input name="end-year" type="text" value="%(end_year_default)s" size="4" /> 177 </td> 178 </tr> 179 <tr> 180 <td class="label"><label>%(end_criteria_label)s</label></td> 181 <td> 182 <input name="end" type="text" value="%(end_criteria_default)s" size="12" /> 183 <input name="end-eval" type="submit" value="%(end_eval_label)s" /> 184 %(end_criteria_eval)s 185 </td> 186 </tr> 187 <tr> 188 <td class="label"><label>%(descriptions_label)s</label></td> 189 <td class="content"> 190 <select name="descriptions"> 191 %(descriptions_list)s 192 </select> 193 </td> 194 </tr> 195 <tr> 196 <td class="label"><label>%(format_label)s</label></td> 197 <td class="content"> 198 <select name="format"> 199 %(format_list)s 200 </select> 201 </td> 202 </tr> 203 <tr> 204 <td class="label"><label>%(parent_label)s</label></td> 205 <td class="content"> 206 <input name="parent" type="text" size="40" value="%(parent_name)s" /> 207 </td> 208 </tr> 209 <tr> 210 <td></td> 211 <td class="buttons"> 212 %(buttons_html)s 213 </td> 214 </tr> 215 </table> 216 ''' % d 217 218 def do_action(self): 219 220 "Write the iCalendar resource." 221 222 _ = self._ 223 form = self.get_form() 224 225 # If no category names or sources exist in the request, an error message 226 # is returned. 227 228 category_names = form.get("category", []) 229 sources = form.get("source", []) 230 231 if not (category_names or sources): 232 return 0, _("No categories or sources specified.") 233 234 write_resource(self.request) 235 return 1, None 236 237 def render_success(self, msg, msgtype=None): 238 239 """ 240 Render neither 'msg' nor 'msgtype' since a resource has already been 241 produced. 242 NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. 243 """ 244 245 pass 246 247 def write_resource(request): 248 249 """ 250 For the given 'request', write an iCalendar summary of the event data found 251 in the categories specified via the "category" request parameter, using the 252 "start" and "end" parameters (if specified). Multiple "category" parameters 253 can be specified. 254 """ 255 256 form = get_form(request) 257 258 category_names = form.get("category", []) 259 remote_sources = form.get("source", []) 260 format = form.get("format", ["iCalendar"])[0] 261 descriptions = form.get("descriptions", ["page"])[0] 262 parent = form.get("parent", [""])[0] 263 resolution = form.get("resolution", ["month"])[0] 264 265 # Look first for a single start and end parameter. If that fails to provide 266 # dates, look for separate start and end parameters, either for complete 267 # dates or for years and months. 268 269 if resolution == "date": 270 calendar_start = getFormDate(request, None, "start") 271 calendar_end = getFormDate(request, None, "end") 272 273 if calendar_start is None: 274 calendar_start = getFormDateTriple(request, "start-year", "start-month", "start-day") 275 if calendar_end is None: 276 calendar_end = getFormDateTriple(request, "end-year", "end-month", "end-day") 277 278 elif resolution == "month": 279 calendar_start = getFormMonth(request, None, "start") 280 calendar_end = getFormMonth(request, None, "end") 281 282 if calendar_start is None: 283 calendar_start = getFormMonthPair(request, "start-year", "start-month") 284 if calendar_end is None: 285 calendar_end = getFormMonthPair(request, "end-year", "end-month") 286 287 # Determine the period and get the events involved. 288 289 pages = getPagesFromResults(getAllCategoryPages(category_names, request), request) 290 events = getEventsFromResources(getEventPages(pages)) 291 events += getEventsFromResources(getEventResources(remote_sources, calendar_start, calendar_end, request)) 292 all_shown_events = getEventsInPeriod(events, getCalendarPeriod(calendar_start, calendar_end)) 293 latest_timestamp = getLatestEventTimestamp(all_shown_events) 294 295 # Output summary data... 296 297 send_headers = get_send_headers(request) 298 299 # Define headers. 300 301 if format == "iCalendar": 302 headers = ["Content-Type: text/calendar; charset=%s" % config.charset] 303 elif format == "RSS": 304 headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset] 305 306 # Define the last modified time. 307 308 if latest_timestamp is not None: 309 headers.append("Last-Modified: %s" % latest_timestamp.as_HTTP_datetime_string()) 310 311 send_headers(headers) 312 313 # iCalendar output... 314 315 if format == "iCalendar": 316 mimetype = "text/calendar" 317 318 # RSS output... 319 320 elif format == "RSS": 321 mimetype = "application/rss+xml" 322 323 # Catch-all... 324 325 else: 326 mimetype = None 327 328 formatEventsForOutputType(all_shown_events, request, mimetype, parent, descriptions, latest_timestamp) 329 330 # Action function. 331 332 def execute(pagename, request): 333 EventAggregatorSummary(pagename, request).render() 334 335 # vim: tabstop=4 expandtab shiftwidth=4