1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - MoinShare library 4 5 @copyright: 2011, 2012 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinSupport import * 10 from MoinMoin import wikiutil 11 from DateSupport import getCurrentTime 12 import re 13 14 escape = wikiutil.escape 15 16 __version__ = "0.1" 17 18 # More Moin 1.9 compatibility functions. 19 20 def has_member(request, groupname, username): 21 if hasattr(request.dicts, "has_member"): 22 return request.dicts.has_member(groupname, username) 23 else: 24 return username in request.dicts.get(groupname, []) 25 26 # Extraction of shared fragments. 27 28 marker_regexp_str = r"([{]{3,}|[}]{3,})" 29 marker_regexp = re.compile(marker_regexp_str, re.MULTILINE | re.DOTALL) # {{{... or }}}... 30 31 # Fragments employ a "moinshare" attribute. 32 33 fragment_prelude = "#!" 34 fragment_attribute = "moinshare" 35 36 def getRegions(s): 37 38 "Parse the string 's', returning a list of shared regions." 39 40 regions = [] 41 marker = None 42 is_region = True 43 44 for match_text in marker_regexp.split(s): 45 46 # Capture section text. 47 48 if is_region and marker: 49 regions[-1] += match_text 50 51 # Handle section markers. 52 53 elif not is_region: 54 55 # Close any open sections, returning to exposed text regions. 56 57 if marker: 58 if match_text.startswith("}") and len(marker) == len(match_text): 59 marker = None 60 61 # Without a current marker, start a section if an appropriate marker 62 # is given. 63 64 elif match_text.startswith("{"): 65 marker = match_text 66 regions.append("") 67 68 # Markers and section text are added to the current region. 69 70 regions[-1] += match_text 71 72 # Exposed text is ignored. 73 74 # The match text alternates between text between markers and the markers 75 # themselves. 76 77 is_region = not is_region 78 79 return regions 80 81 def getFragmentsFromRegions(regions): 82 83 """ 84 Return fragments from the given 'regions', each having the form 85 (format, arguments, body text). 86 """ 87 88 fragments = [] 89 90 for region in regions: 91 body = region.lstrip("{").rstrip("}").lstrip() 92 if body.startswith(fragment_prelude): 93 arguments, body = body[len(fragment_prelude):].split("\n", 1) 94 95 # Get any parser/format declaration. 96 97 if arguments and not arguments[0].isspace(): 98 format, arguments = arguments.split(None, 1) 99 else: 100 format = None 101 102 # Get the attributes/arguments for the region. 103 104 attributes = parseAttributes(arguments, False) 105 106 # If the format is the MoinShare attribute, move it into the 107 # dictionary. 108 109 if format.lower() == fragment_attribute: 110 attributes[fragment_attribute] = True 111 format = None 112 113 # Only collect appropriate regions. 114 115 if attributes.has_key(fragment_attribute): 116 fragments.append((format, attributes, body)) 117 118 return fragments 119 120 def getFragments(s): 121 122 """ 123 Return fragments for the given string 's', each having the form 124 (arguments, body text). 125 """ 126 127 return getFragmentsFromRegions(getRegions(s)) 128 129 def getOutputTypes(request, format): 130 131 """ 132 Using the 'request' and the 'format' of a fragment, return the media types 133 available for the fragment. 134 """ 135 136 # This uses an extended parser API method if available. 137 138 parser = getParserClass(request, format) 139 if hasattr(parser, "getOutputTypes"): 140 return parser.getOutputTypes() 141 else: 142 return ["text/html"] 143 144 def getPreferredOutputTypes(request, mimetypes): 145 146 """ 147 Using the 'request', perform content negotiation, obtaining mimetypes common 148 to the fragment (given by 'mimetypes') and the client (found in the Accept 149 header). 150 """ 151 152 accept = getHeader(request, "Accept", "HTTP") 153 if accept: 154 prefs = getContentPreferences(accept) 155 return prefs.get_preferred_types(mimetypes) 156 else: 157 return mimetypes 158 159 def getUpdatedTime(metadata): 160 161 """ 162 Return the last updated time based on the given 'metadata', using the 163 current time if no explicit last modified time is specified. 164 """ 165 166 # NOTE: We could attempt to get the last edit time of a fragment. 167 168 latest_timestamp = metadata.get("last-modified") 169 if latest_timestamp: 170 return latest_timestamp.as_ISO8601_datetime_string() 171 else: 172 return getCurrentTime().as_ISO8601_datetime_string() 173 174 # vim: tabstop=4 expandtab shiftwidth=4