MoinContentSuite

Changeset

1:b78423a02662
2010-08-15 Paul Boddie raw files shortlog changelog graph Moved the link details retrieval and editing into the action, providing a default form for the action.
actions/AddLinkToPage.py (file) macros/AddLinkToPage.py (file)
     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):
     2.1 --- a/macros/AddLinkToPage.py	Sun Aug 15 01:52:41 2010 +0200
     2.2 +++ b/macros/AddLinkToPage.py	Sun Aug 15 18:31:26 2010 +0200
     2.3 @@ -12,58 +12,6 @@
     2.4  Dependencies = ["pages"]
     2.5  
     2.6  from MoinMoin import wikiutil
     2.7 -from MoinMoin.PageEditor import PageEditor
     2.8 -from MoinContentSupport import get_form
     2.9 -import urllib
    2.10 -import re
    2.11 -
    2.12 -title_pattern = re.compile(ur'<(?P<tag>title|h\d)(\s.*?)?>(?P<title>.*?)</(?P=tag)>', re.MULTILINE | re.UNICODE | re.DOTALL)
    2.13 -paragraph_pattern = re.compile(ur'<p(\s.*?)?>(?P<text>.*?)(?=<p(\s.*?)?>|</p>)', re.MULTILINE | re.UNICODE | re.DOTALL)
    2.14 -tag_pattern = re.compile(ur'<.*?>', re.MULTILINE | re.UNICODE | re.DOTALL)
    2.15 -
    2.16 -def get_link_info(link):
    2.17 -
    2.18 -    "Get information from the given 'link'."
    2.19 -
    2.20 -    # NOTE: Insist on remote URLs!
    2.21 -
    2.22 -    try:
    2.23 -        f = urllib.urlopen(link)
    2.24 -    except IOError:
    2.25 -        return None
    2.26 -
    2.27 -    try:
    2.28 -        s = f.read()
    2.29 -        first_title = ""
    2.30 -
    2.31 -        for title_match in title_pattern.finditer(s):
    2.32 -            title = title_match.group("title").strip()
    2.33 -            start, end = title_match.span()
    2.34 -
    2.35 -            if not first_title:
    2.36 -                first_title = title
    2.37 -
    2.38 -            for intro_match in paragraph_pattern.finditer(s[end:]):
    2.39 -                intro = get_flattened_content(intro_match.group("text")).strip()
    2.40 -                if intro:
    2.41 -                    return title, intro
    2.42 -    finally:
    2.43 -        f.close()
    2.44 -
    2.45 -    return first_title, ""
    2.46 -
    2.47 -def get_flattened_content(s):
    2.48 -
    2.49 -    "Get HTML or XHTML without the tags."
    2.50 -
    2.51 -    l = []
    2.52 -    last = 0
    2.53 -    for match in tag_pattern.finditer(s):
    2.54 -        start, end = match.span()
    2.55 -        l.append(s[last:start])
    2.56 -        last = end
    2.57 -    l.append(s[last:])
    2.58 -    return "".join(l).replace("\n", " ")
    2.59  
    2.60  # Macro functions.
    2.61  
    2.62 @@ -76,11 +24,8 @@
    2.63      request = macro.request
    2.64      formatter = macro.formatter
    2.65      page = formatter.page
    2.66 -    form = get_form(request)
    2.67      _ = macro._
    2.68  
    2.69 -    output = []
    2.70 -
    2.71      # Interpret the arguments.
    2.72  
    2.73      try:
    2.74 @@ -98,102 +43,27 @@
    2.75  
    2.76      insert_before = "before" in parsed_args[1:] or not ("after" in parsed_args[1:])
    2.77  
    2.78 -    # If the request refers to this macro, another kind of form will be shown.
    2.79 -
    2.80 -    active_identifier = form.get('add_link_to_page', [None])[0]
    2.81 -    link = form.get('add_link_to_page_link', [None])[0]
    2.82 -
    2.83 -    # Test for usage of this macro.
    2.84 -    # Where this macro is not active, don't do anything.
    2.85 -
    2.86 -    if identifier != active_identifier:
    2.87 -        show_macro = 1
    2.88 -
    2.89 -    # Otherwise, show a form containing link details.
    2.90 -
    2.91 -    else:
    2.92 -
    2.93 -        # Acquire information from the link.
    2.94 -
    2.95 -        link_info = get_link_info(link)
    2.96 -
    2.97 -        # NOTE: Perhaps show a message upon success/failure.
    2.98 +    # Show the fields for link submission.
    2.99  
   2.100 -        if link_info is None:
   2.101 -            show_macro = 1
   2.102 -
   2.103 -        # Information was retrieved and is now shown.
   2.104 -
   2.105 -        else:
   2.106 -            title, introduction = link_info
   2.107 -
   2.108 -            # Show a form containing the retrieved information suitable for the
   2.109 -            # corresponding action.
   2.110 -
   2.111 -            output.append(u'<form class="macro" method="POST" action="%s/%s">' % (
   2.112 -                request.getScriptname(), wikiutil.quoteWikinameURL(page.page_name)))
   2.113 -
   2.114 -            output.append(u'''
   2.115 -    <input type="hidden" name="identifier" value="%(identifier)s" />
   2.116 -    <input type="hidden" name="doit" value="1" />
   2.117 -    <input type="hidden" name="insert_before" value="%(insert_before)s" />
   2.118 -    <input type="hidden" name="action" value="AddLinkToPage" />''' % {
   2.119 -                "identifier" : wikiutil.escape(identifier, 1),
   2.120 -                "insert_before" : insert_before and "true" or ""
   2.121 -                })
   2.122 +    d = {
   2.123 +        "script_name" : request.getScriptname(),
   2.124 +        "page_url" : wikiutil.quoteWikinameURL(page.page_name),
   2.125 +        "identifier" : wikiutil.escape(identifier, 1),
   2.126 +        "insert_before" : insert_before and "true" or "",
   2.127 +        "submit_label" : wikiutil.escape(_("Add link"))
   2.128 +        }
   2.129  
   2.130 -            output.append(u'''
   2.131 -    <table>
   2.132 -      <tr>
   2.133 -        <th>%(url_label)s</th>
   2.134 -        <td><input type="text" name="link" value="%(link)s" /></td>
   2.135 -      </tr>
   2.136 -      <tr>
   2.137 -        <th>%(title_label)s</th>
   2.138 -        <td><input type="text" name="title" value="%(title)s" /></td>
   2.139 -      </tr>
   2.140 -      <tr>
   2.141 -        <th>%(intro_label)s</th>
   2.142 -        <td><input type="text" name="introduction" value="%(intro)s" /></td>
   2.143 -      </tr>
   2.144 -      <tr>
   2.145 -        <th>%(description_label)s</th>
   2.146 -        <td><input type="text" name="description" /></td>
   2.147 -      </tr>
   2.148 -      <tr>
   2.149 -        <td colspan="2"><input type="submit" value="%(submit_label)s" /></td>
   2.150 -      </tr>
   2.151 -    </table>''' % {
   2.152 -                "link" : wikiutil.escape(link, 1),
   2.153 -                "title" : wikiutil.escape(title, 1),
   2.154 -                "intro" : wikiutil.escape(introduction, 1),
   2.155 -                "url_label" : wikiutil.escape(_("URL")),
   2.156 -                "title_label" : wikiutil.escape(_("Title")),
   2.157 -                "intro_label" : wikiutil.escape(_("Introduction")),
   2.158 -                "description_label" : wikiutil.escape(_("Description")),
   2.159 -                "submit_label" : wikiutil.escape(_("Submit link"))
   2.160 -                })
   2.161 +    html = '''
   2.162 +<form class="macro" method="POST" action="%(script_name)s/%(page_url)s">
   2.163 +  <input type="hidden" name="action" value="AddLinkToPage" />
   2.164 +  <input type="hidden" name="identifier" value="%(identifier)s" />
   2.165 +  <input type="hidden" name="insert_before" value="%(insert_before)s" />
   2.166 +  <div>
   2.167 +    <input type="text" name="link" />
   2.168 +    <input type="submit" value="%(submit_label)s" />
   2.169 +  </div>
   2.170 +</form>''' % d
   2.171  
   2.172 -            output.append(u'</form>')
   2.173 -
   2.174 -            # Don't show the macro.
   2.175 -
   2.176 -            show_macro = 0
   2.177 -
   2.178 -    # If the macro is to be shown, emit the usual fields.
   2.179 -
   2.180 -    if show_macro:
   2.181 -        output.append(u'<form class="macro" method="POST" action="%s/%s">' % (
   2.182 -            request.getScriptname(), wikiutil.quoteWikinameURL(page.page_name)))
   2.183 -        output.append(u'<input type="hidden" name="add_link_to_page" value="%s" />' %
   2.184 -            wikiutil.escape(identifier, 1))
   2.185 -        output.append(u'<div>')
   2.186 -        output.append(u'<input type="text" name="add_link_to_page_link" />')
   2.187 -        output.append(u'<input type="submit" value="%s" />' %
   2.188 -            wikiutil.escape(_("Add link")))
   2.189 -        output.append(u'</div>')
   2.190 -        output.append(u'</form>')
   2.191 -
   2.192 -    return formatter.rawHTML('\n'.join(output))
   2.193 +    return formatter.rawHTML(html)
   2.194  
   2.195  # vim: tabstop=4 expandtab shiftwidth=4