1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - MoinSupport library (derived from EventAggregatorSupport) 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 2005-2008 MoinMoin:ThomasWaldmann. 8 @license: GNU GPL (v2 or later), see COPYING.txt for details. 9 """ 10 11 from DateSupport import * 12 from MoinMoin.Page import Page 13 from MoinMoin import wikiutil 14 import re 15 import time 16 17 __version__ = "0.1" 18 19 # Content type parsing. 20 21 encoding_regexp_str = ur'(?P<content_type>[^\s;]*)(?:;\s*charset=(?P<encoding>[-A-Za-z0-9]+))?' 22 encoding_regexp = re.compile(encoding_regexp_str) 23 24 # Utility functions. 25 26 def getContentTypeAndEncoding(content_type): 27 m = encoding_regexp.search(content_type) 28 if m: 29 return m.group("content_type"), m.group("encoding") 30 else: 31 return None, None 32 33 def int_or_none(x): 34 if x is None: 35 return x 36 else: 37 return int(x) 38 39 # Utility classes and associated functions. 40 41 class Form: 42 43 """ 44 A wrapper preserving MoinMoin 1.8.x (and earlier) behaviour in a 1.9.x 45 environment. 46 """ 47 48 def __init__(self, form): 49 self.form = form 50 51 def has_key(self, name): 52 return not not self.form.getlist(name) 53 54 def get(self, name, default=None): 55 values = self.form.getlist(name) 56 if not values: 57 return default 58 else: 59 return values 60 61 def __getitem__(self, name): 62 return self.form.getlist(name) 63 64 class ActionSupport: 65 66 """ 67 Work around disruptive MoinMoin changes in 1.9, and also provide useful 68 convenience methods. 69 """ 70 71 def get_form(self): 72 return get_form(self.request) 73 74 def _get_selected(self, value, input_value): 75 76 """ 77 Return the HTML attribute text indicating selection of an option (or 78 otherwise) if 'value' matches 'input_value'. 79 """ 80 81 return input_value is not None and value == input_value and 'selected="selected"' or '' 82 83 def _get_selected_for_list(self, value, input_values): 84 85 """ 86 Return the HTML attribute text indicating selection of an option (or 87 otherwise) if 'value' matches one of the 'input_values'. 88 """ 89 90 return value in input_values and 'selected="selected"' or '' 91 92 def _get_input(self, form, name, default=None): 93 94 """ 95 Return the input from 'form' having the given 'name', returning either 96 the input converted to an integer or the given 'default' (optional, None 97 if not specified). 98 """ 99 100 value = form.get(name, [None])[0] 101 if not value: # true if 0 obtained 102 return default 103 else: 104 return int(value) 105 106 def get_form(request): 107 108 "Work around disruptive MoinMoin changes in 1.9." 109 110 if hasattr(request, "values"): 111 return Form(request.values) 112 else: 113 return request.form 114 115 class send_headers_cls: 116 117 """ 118 A wrapper to preserve MoinMoin 1.8.x (and earlier) request behaviour in a 119 1.9.x environment. 120 """ 121 122 def __init__(self, request): 123 self.request = request 124 125 def __call__(self, headers): 126 for header in headers: 127 parts = header.split(":") 128 self.request.headers.add(parts[0], ":".join(parts[1:])) 129 130 def get_send_headers(request): 131 132 "Return a function that can send response headers." 133 134 if hasattr(request, "http_headers"): 135 return request.http_headers 136 elif hasattr(request, "emit_http_headers"): 137 return request.emit_http_headers 138 else: 139 return send_headers_cls(request) 140 141 def escattr(s): 142 return wikiutil.escape(s, 1) 143 144 def getPathInfo(request): 145 if hasattr(request, "getPathinfo"): 146 return request.getPathinfo() 147 else: 148 return request.path 149 150 # Page access functions. 151 152 def getPageURL(page): 153 154 "Return the URL of the given 'page'." 155 156 request = page.request 157 return request.getQualifiedURL(page.url(request, relative=0)) 158 159 def getFormat(page): 160 161 "Get the format used on the given 'page'." 162 163 return page.pi["format"] 164 165 def getMetadata(page): 166 167 """ 168 Return a dictionary containing items describing for the given 'page' the 169 page's "created" time, "last-modified" time, "sequence" (or revision number) 170 and the "last-comment" made about the last edit. 171 """ 172 173 request = page.request 174 175 # Get the initial revision of the page. 176 177 revisions = page.getRevList() 178 event_page_initial = Page(request, page.page_name, rev=revisions[-1]) 179 180 # Get the created and last modified times. 181 182 initial_revision = getPageRevision(event_page_initial) 183 184 metadata = {} 185 metadata["created"] = initial_revision["timestamp"] 186 latest_revision = getPageRevision(page) 187 metadata["last-modified"] = latest_revision["timestamp"] 188 metadata["sequence"] = len(revisions) - 1 189 metadata["last-comment"] = latest_revision["comment"] 190 191 return metadata 192 193 def getPageRevision(page): 194 195 "Return the revision details dictionary for the given 'page'." 196 197 # From Page.edit_info... 198 199 if hasattr(page, "editlog_entry"): 200 line = page.editlog_entry() 201 else: 202 line = page._last_edited(page.request) # MoinMoin 1.5.x and 1.6.x 203 204 # Similar to Page.mtime_usecs behaviour... 205 206 if line: 207 timestamp = line.ed_time_usecs 208 mtime = wikiutil.version2timestamp(long(timestamp)) # must be long for py 2.2.x 209 comment = line.comment 210 else: 211 mtime = 0 212 comment = "" 213 214 # Leave the time zone empty. 215 216 return {"timestamp" : DateTime(time.gmtime(mtime)[:6] + (None,)), "comment" : comment} 217 218 # User interface functions. 219 220 def getParameter(request, name, default=None): 221 222 """ 223 Using the given 'request', return the value of the parameter with the given 224 'name', returning the optional 'default' (or None) if no value was supplied 225 in the 'request'. 226 """ 227 228 return get_form(request).get(name, [default])[0] 229 230 def getQualifiedParameter(request, prefix, argname, default=None): 231 232 """ 233 Using the given 'request', 'prefix' and 'argname', retrieve the value of the 234 qualified parameter, returning the optional 'default' (or None) if no value 235 was supplied in the 'request'. 236 """ 237 238 argname = getQualifiedParameterName(prefix, argname) 239 return getParameter(request, argname, default) 240 241 def getQualifiedParameterName(prefix, argname): 242 243 """ 244 Return the qualified parameter name using the given 'prefix' and 'argname'. 245 """ 246 247 if prefix is None: 248 return argname 249 else: 250 return "%s-%s" % (prefix, argname) 251 252 # Page-related functions. 253 254 def getPrettyPageName(page): 255 256 "Return a nicely formatted title/name for the given 'page'." 257 258 title = page.split_title(force=1) 259 return getPrettyTitle(title) 260 261 def linkToPage(request, page, text, query_string=None): 262 263 """ 264 Using 'request', return a link to 'page' with the given link 'text' and 265 optional 'query_string'. 266 """ 267 268 text = wikiutil.escape(text) 269 return page.link_to_raw(request, text, query_string) 270 271 def linkToResource(url, request, text, query_string=None): 272 273 """ 274 Using 'request', return a link to 'url' with the given link 'text' and 275 optional 'query_string'. 276 """ 277 278 if query_string: 279 query_string = wikiutil.makeQueryString(query_string) 280 url = "%s?%s" % (url, query_string) 281 282 formatter = request.page and getattr(request.page, "formatter", None) or request.html_formatter 283 284 output = [] 285 output.append(formatter.url(1, url)) 286 output.append(formatter.text(text)) 287 output.append(formatter.url(0)) 288 return "".join(output) 289 290 def getFullPageName(parent, title): 291 292 """ 293 Return a full page name from the given 'parent' page (can be empty or None) 294 and 'title' (a simple page name). 295 """ 296 297 if parent: 298 return "%s/%s" % (parent.rstrip("/"), title) 299 else: 300 return title 301 302 # vim: tabstop=4 expandtab shiftwidth=4