1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - MoinShare library 4 5 @copyright: 2011, 2012, 2013 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from ContentTypeSupport import getContentPreferences 10 from DateSupport import getCurrentTime 11 from MoinSupport import * 12 from MoinMoin import wikiutil 13 import re 14 15 try: 16 from cStringIO import StringIO 17 except ImportError: 18 from StringIO import StringIO 19 20 escape = wikiutil.escape 21 _getFragments = getFragments 22 23 __version__ = "0.1" 24 25 # More Moin 1.9 compatibility functions. 26 27 def has_member(request, groupname, username): 28 if hasattr(request.dicts, "has_member"): 29 return request.dicts.has_member(groupname, username) 30 else: 31 return username in request.dicts.get(groupname, []) 32 33 # Fragments employ a "moinshare" attribute. 34 35 fragment_attribute = "moinshare" 36 37 def getFragments(s): 38 39 "Return all fragments in 's' having the MoinShare fragment attribute." 40 41 fragments = [] 42 for format, attributes, body in _getFragments(s): 43 if attributes.has_key(fragment_attribute): 44 fragments.append((format, attributes, body)) 45 return fragments 46 47 def getOutputTypes(request, format): 48 49 """ 50 Using the 'request' and the 'format' of a fragment, return the media types 51 available for the fragment. 52 """ 53 54 # This uses an extended parser API method if available. 55 56 parser = getParserClass(request, format) 57 if hasattr(parser, "getOutputTypes"): 58 return parser.getOutputTypes() 59 else: 60 return ["text/html"] 61 62 def getPreferredOutputTypes(request, mimetypes): 63 64 """ 65 Using the 'request', perform content negotiation, obtaining mimetypes common 66 to the fragment (given by 'mimetypes') and the client (found in the Accept 67 header). 68 """ 69 70 accept = getHeader(request, "Accept", "HTTP") 71 if accept: 72 prefs = getContentPreferences(accept) 73 return prefs.get_preferred_types(mimetypes) 74 else: 75 return mimetypes 76 77 def getUpdatedTime(metadata): 78 79 """ 80 Return the last updated time based on the given 'metadata', using the 81 current time if no explicit last modified time is specified. 82 """ 83 84 # NOTE: We could attempt to get the last edit time of a fragment. 85 86 latest_timestamp = metadata.get("last-modified") 87 if latest_timestamp: 88 return latest_timestamp.as_ISO8601_datetime_string() 89 else: 90 return getCurrentTime().as_ISO8601_datetime_string() 91 92 def getUpdateSources(request, sources_page): 93 94 """ 95 Using the 'request', return the update sources defined on the given 96 'sources_page'. 97 """ 98 99 # Remote sources are accessed via dictionary page definitions. 100 101 return getWikiDict(sources_page, request) 102 103 def getUpdateFragmentsFromPage(page, request): 104 105 """ 106 Get update fragments from the given 'page' using the 'request'. A list of 107 update descriptions is returned, each being a tuple of the form... 108 109 (fragment identifer, summary text, preferred mimetypes, textual content, 110 updated datetime) 111 """ 112 113 updates = [] 114 115 # NOTE: Use the updated datetime from the page for updates. 116 # NOTE: The published and updated details would need to be deduced from 117 # NOTE: the page history instead of being taken from the page as a whole. 118 119 metadata = getMetadata(page) 120 updated = getUpdatedTime(metadata) 121 122 # Get the fragment regions for the page. 123 124 for n, (format, attributes, body) in enumerate(getFragments(page.get_raw_body())): 125 126 # Produce a fragment identifier. 127 # NOTE: Choose a more robust identifier where none is explicitly given. 128 129 fragment = attributes.get("fragment", str(n)) 130 summary = attributes.get("summary", "Update #%d" % n) 131 132 # Get the preferred content types available for the fragment. 133 134 preferred = getPreferredOutputTypes(request, getOutputTypes(request, format)) 135 136 # Try and obtain some suitable content for the entry. 137 # NOTE: Could potentially get a summary for the fragment. 138 139 content = None 140 141 if "text/html" in preferred: 142 parser_cls = getParserClass(request, format) 143 parser = parser_cls(body, request) 144 145 if format == "html": 146 content = body 147 elif hasattr(parser, "formatForOutputType"): 148 s = StringIO() 149 parser.formatForOutputType("text/html", write=s.write) 150 content = s.getvalue() 151 else: 152 fmt = request.html_formatter 153 fmt.setPage(page) 154 content = formatText(body, request, fmt, parser_cls) 155 156 updates.append((fragment, summary, preferred, content, updated)) 157 158 return updates 159 160 # vim: tabstop=4 expandtab shiftwidth=4