1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - AddLinkToPage 4 5 Add a link using a form in the page, getting details of the linked document 6 and inserting them with the link itself. 7 8 @copyright: 2010 Paul Boddie <paul@boddie.org.uk> 9 @license: GNU GPL, see COPYING for details. 10 """ 11 12 Dependencies = ["pages"] 13 14 from MoinMoin import wikiutil 15 from MoinMoin.PageEditor import PageEditor 16 from MoinContentSupport import get_form 17 import urllib 18 import re 19 20 title_pattern = re.compile(ur'<(?P<tag>title|h\d)(\s.*?)?>(?P<title>.*?)</(?P=tag)>', re.MULTILINE | re.UNICODE | re.DOTALL) 21 paragraph_pattern = re.compile(ur'<p(\s.*?)?>(?P<text>.*?)(?=<p(\s.*?)?>|</p>)', re.MULTILINE | re.UNICODE | re.DOTALL) 22 tag_pattern = re.compile(ur'<.*?>', re.MULTILINE | re.UNICODE | re.DOTALL) 23 24 def get_link_info(link): 25 26 "Get information from the given 'link'." 27 28 # NOTE: Insist on remote URLs! 29 30 try: 31 f = urllib.urlopen(link) 32 except IOError: 33 return None 34 35 try: 36 s = f.read() 37 first_title = "" 38 39 for title_match in title_pattern.finditer(s): 40 title = title_match.group("title").strip() 41 start, end = title_match.span() 42 43 if not first_title: 44 first_title = title 45 46 for intro_match in paragraph_pattern.finditer(s[end:]): 47 intro = get_flattened_content(intro_match.group("text")).strip() 48 if intro: 49 return title, intro 50 finally: 51 f.close() 52 53 return first_title, "" 54 55 def get_flattened_content(s): 56 57 "Get HTML or XHTML without the tags." 58 59 l = [] 60 last = 0 61 for match in tag_pattern.finditer(s): 62 start, end = match.span() 63 l.append(s[last:start]) 64 last = end 65 l.append(s[last:]) 66 return "".join(l).replace("\n", " ") 67 68 # Macro functions. 69 70 def execute(macro, args): 71 72 """ 73 Execute the 'macro' with the given 'args': 74 """ 75 76 request = macro.request 77 formatter = macro.formatter 78 page = formatter.page 79 form = get_form(request) 80 _ = macro._ 81 82 output = [] 83 84 # Interpret the arguments. 85 86 try: 87 parsed_args = args and wikiutil.parse_quoted_separated(args, name_value=False) or [] 88 except AttributeError: 89 parsed_args = args.split(",") 90 91 parsed_args = [arg for arg in parsed_args if arg] 92 93 # The macro's identifier should always appear first. 94 95 identifier = parsed_args[0] 96 97 # Look for keywords determining the action of the macro. 98 99 insert_before = "before" in parsed_args[1:] or not ("after" in parsed_args[1:]) 100 101 # If the request refers to this macro, another kind of form will be shown. 102 103 active_identifier = form.get('add_link_to_page', [None])[0] 104 link = form.get('add_link_to_page_link', [None])[0] 105 106 # Test for usage of this macro. 107 # Where this macro is not active, don't do anything. 108 109 if identifier != active_identifier: 110 show_macro = 1 111 112 # Otherwise, show a form containing link details. 113 114 else: 115 116 # Acquire information from the link. 117 118 link_info = get_link_info(link) 119 120 # NOTE: Perhaps show a message upon success/failure. 121 122 if link_info is None: 123 show_macro = 1 124 125 # Information was retrieved and is now shown. 126 127 else: 128 title, introduction = link_info 129 130 # Show a form containing the retrieved information suitable for the 131 # corresponding action. 132 133 output.append(u'<form class="macro" method="POST" action="%s/%s">' % ( 134 request.getScriptname(), wikiutil.quoteWikinameURL(page.page_name))) 135 136 output.append(u''' 137 <input type="hidden" name="identifier" value="%(identifier)s" /> 138 <input type="hidden" name="doit" value="1" /> 139 <input type="hidden" name="insert_before" value="%(insert_before)s" /> 140 <input type="hidden" name="action" value="AddLinkToPage" />''' % { 141 "identifier" : wikiutil.escape(identifier, 1), 142 "insert_before" : insert_before and "true" or "" 143 }) 144 145 output.append(u''' 146 <table> 147 <tr> 148 <th>%(url_label)s</th> 149 <td><input type="text" name="link" value="%(link)s" /></td> 150 </tr> 151 <tr> 152 <th>%(title_label)s</th> 153 <td><input type="text" name="title" value="%(title)s" /></td> 154 </tr> 155 <tr> 156 <th>%(intro_label)s</th> 157 <td><input type="text" name="introduction" value="%(intro)s" /></td> 158 </tr> 159 <tr> 160 <th>%(description_label)s</th> 161 <td><input type="text" name="description" /></td> 162 </tr> 163 <tr> 164 <td colspan="2"><input type="submit" value="%(submit_label)s" /></td> 165 </tr> 166 </table>''' % { 167 "link" : wikiutil.escape(link, 1), 168 "title" : wikiutil.escape(title, 1), 169 "intro" : wikiutil.escape(introduction, 1), 170 "url_label" : wikiutil.escape(_("URL")), 171 "title_label" : wikiutil.escape(_("Title")), 172 "intro_label" : wikiutil.escape(_("Introduction")), 173 "description_label" : wikiutil.escape(_("Description")), 174 "submit_label" : wikiutil.escape(_("Submit link")) 175 }) 176 177 output.append(u'</form>') 178 179 # Don't show the macro. 180 181 show_macro = 0 182 183 # If the macro is to be shown, emit the usual fields. 184 185 if show_macro: 186 output.append(u'<form class="macro" method="POST" action="%s/%s">' % ( 187 request.getScriptname(), wikiutil.quoteWikinameURL(page.page_name))) 188 output.append(u'<input type="hidden" name="add_link_to_page" value="%s" />' % 189 wikiutil.escape(identifier, 1)) 190 output.append(u'<div>') 191 output.append(u'<input type="text" name="add_link_to_page_link" />') 192 output.append(u'<input type="submit" value="%s" />' % 193 wikiutil.escape(_("Add link"))) 194 output.append(u'</div>') 195 output.append(u'</form>') 196 197 return formatter.rawHTML('\n'.join(output)) 198 199 # vim: tabstop=4 expandtab shiftwidth=4