1.1 --- a/actions/AddLinkToPage.py Sun Aug 15 01:52:41 2010 +0200
1.2 +++ b/actions/AddLinkToPage.py Sun Aug 15 18:31:26 2010 +0200
1.3 @@ -11,20 +11,142 @@
1.4
1.5 Dependencies = ['pages']
1.6
1.7 +from MoinMoin import wikiutil
1.8 from MoinMoin.action import ActionBase
1.9 from MoinMoin.PageEditor import PageEditor
1.10 from MoinContentSupport import ActionSupport
1.11 +import urllib
1.12 import re
1.13
1.14 +# Page parsing.
1.15 +
1.16 macro_pattern = re.compile(ur'^(?P<leading>.*?)<<AddLinkToPage\((?P<identifier>[^\s,)]+).*?\)>>(?P<trailing>.*)$',
1.17 re.MULTILINE | re.UNICODE)
1.18
1.19 +# Link visiting and parsing.
1.20 +
1.21 +title_pattern = re.compile(ur'<(?P<tag>title|h\d)(\s.*?)?>(?P<title>.*?)</(?P=tag)>', re.MULTILINE | re.UNICODE | re.DOTALL)
1.22 +paragraph_pattern = re.compile(ur'<p(\s.*?)?>(?P<text>.*?)(?=<p(\s.*?)?>|</p>)', re.MULTILINE | re.UNICODE | re.DOTALL)
1.23 +tag_pattern = re.compile(ur'<.*?>', re.MULTILINE | re.UNICODE | re.DOTALL)
1.24 +
1.25 +def get_link_info(link):
1.26 +
1.27 + "Get information from the given 'link'."
1.28 +
1.29 + # NOTE: Insist on remote URLs!
1.30 +
1.31 + try:
1.32 + f = urllib.urlopen(link)
1.33 + except IOError:
1.34 + return None
1.35 +
1.36 + try:
1.37 + s = f.read()
1.38 + first_title = ""
1.39 +
1.40 + for title_match in title_pattern.finditer(s):
1.41 + title = title_match.group("title").strip()
1.42 + start, end = title_match.span()
1.43 +
1.44 + if not first_title:
1.45 + first_title = title
1.46 +
1.47 + for intro_match in paragraph_pattern.finditer(s[end:]):
1.48 + intro = get_flattened_content(intro_match.group("text")).strip()
1.49 + if intro:
1.50 + return title, intro
1.51 + finally:
1.52 + f.close()
1.53 +
1.54 + return first_title, ""
1.55 +
1.56 +def get_flattened_content(s):
1.57 +
1.58 + "Get HTML or XHTML without the tags."
1.59 +
1.60 + l = []
1.61 + last = 0
1.62 + for match in tag_pattern.finditer(s):
1.63 + start, end = match.span()
1.64 + l.append(s[last:start])
1.65 + last = end
1.66 + l.append(s[last:])
1.67 + return "".join(l).replace("\n", " ")
1.68 +
1.69 # Action class and supporting functions.
1.70
1.71 class AddLinkToPage(ActionBase, ActionSupport):
1.72
1.73 "An action adding links to pages."
1.74
1.75 + def get_form_html(self, buttons_html):
1.76 + _ = self._
1.77 + request = self.request
1.78 + page = self.page
1.79 + form = self.get_form()
1.80 +
1.81 + identifier = form.get("identifier", [None])[0]
1.82 + link = form.get("link", [None])[0]
1.83 + insert_before = form.get('insert_before', [""])[0]
1.84 + title = ""
1.85 + introduction = ""
1.86 +
1.87 + # Acquire information from the link.
1.88 +
1.89 + if link is not None:
1.90 + link_info = get_link_info(link)
1.91 +
1.92 + # NOTE: Perhaps show a message upon success/failure.
1.93 +
1.94 + if link_info is not None:
1.95 + title, introduction = link_info
1.96 +
1.97 + d = {
1.98 + "identifier" : wikiutil.escape(identifier, 1),
1.99 + "insert_before" : insert_before and "true" or "",
1.100 + "link" : wikiutil.escape(link, 1),
1.101 + "title" : wikiutil.escape(title, 1),
1.102 + "intro" : wikiutil.escape(introduction, 1),
1.103 + "url_label" : wikiutil.escape(_("URL")),
1.104 + "title_label" : wikiutil.escape(_("Title")),
1.105 + "intro_label" : wikiutil.escape(_("Introduction")),
1.106 + "description_label" : wikiutil.escape(_("Description")),
1.107 + "submit_label" : wikiutil.escape(_("Submit link")),
1.108 + "script_name" : request.getScriptname(),
1.109 + "page_url" : wikiutil.quoteWikinameURL(page.page_name)
1.110 + }
1.111 +
1.112 + html = '''
1.113 +<form class="macro" method="POST" action="%(script_name)s/%(page_url)s">
1.114 + <input type="hidden" name="identifier" value="%(identifier)s" />
1.115 + <input type="hidden" name="doit" value="1" />
1.116 + <input type="hidden" name="insert_before" value="%(insert_before)s" />
1.117 + <input type="hidden" name="action" value="AddLinkToPage" />
1.118 + <table>
1.119 + <tr>
1.120 + <td class="label">%(url_label)s</td>
1.121 + <td><input type="text" name="link" value="%(link)s" size="40" /></td>
1.122 + </tr>
1.123 + <tr>
1.124 + <td class="label">%(title_label)s</td>
1.125 + <td><input type="text" name="title" value="%(title)s" size="40" /></td>
1.126 + </tr>
1.127 + <tr>
1.128 + <td class="label">%(intro_label)s</td>
1.129 + <td><textarea name="introduction" cols="40" rows="3">%(intro)s</textarea></td>
1.130 + </tr>
1.131 + <tr>
1.132 + <td class="label">%(description_label)s</td>
1.133 + <td><input type="text" name="description" size="40" /></td>
1.134 + </tr>
1.135 + <tr>
1.136 + <td colspan="2"><input type="submit" value="%(submit_label)s" /></td>
1.137 + </tr>
1.138 + </table>
1.139 +</form>''' % d
1.140 +
1.141 + return html
1.142 +
1.143 def do_action(self):
1.144
1.145 "Create the new event."
1.146 @@ -35,12 +157,11 @@
1.147 # If no title exists in the request, an error message is returned.
1.148
1.149 identifier = form.get("identifier", [None])[0]
1.150 + link = form.get("link", [None])[0]
1.151
1.152 if not identifier:
1.153 return 0, _("No identifier specified.")
1.154
1.155 - link = form.get("link", [None])[0]
1.156 -
1.157 if not link:
1.158 return 0, _("No link specified.")
1.159
1.160 @@ -80,7 +201,7 @@
1.161 # NOTE: Should support different formatting options.
1.162
1.163 link_details = "%s[[%s%s]]%s" % (
1.164 - introduction and ('"%s" ' % formatter.escapedText(introduction)) or "",
1.165 + introduction and (get_verbatim('"%s" ' % introduction)) or "",
1.166 link,
1.167 title and ('|%s' % title) or "",
1.168 description and (" - ''%s''" % description) or ""
1.169 @@ -119,6 +240,20 @@
1.170 request.http_redirect(page.url(request))
1.171 return 1, None
1.172
1.173 +def get_verbatim(s):
1.174 +
1.175 + "Return 's' encoded as verbatim text."
1.176 +
1.177 + output = []
1.178 +
1.179 + for part in s.split('"'):
1.180 + if part:
1.181 + output.append('<<Verbatim("%s")>>' % part)
1.182 + else:
1.183 + output.append('')
1.184 +
1.185 + return '"'.join(output)
1.186 +
1.187 # Action function.
1.188
1.189 def execute(pagename, request):