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