Back to index

moin  1.9.0~rc2
diff.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - show diff between 2 page revisions
00004 
00005     @copyright: 2000-2004 Juergen Hermann <jh@web.de>,
00006                 2006-2008 MoinMoin:ThomasWaldmann
00007     @license: GNU GPL, see COPYING for details.
00008 """
00009 
00010 from MoinMoin import wikiutil
00011 from MoinMoin.logfile import editlog
00012 from MoinMoin.Page import Page
00013 
00014 def execute(pagename, request):
00015     """ Handle "action=diff"
00016         checking for either a "rev=formerrevision" parameter
00017         or rev1 and rev2 parameters
00018     """
00019     if not request.user.may.read(pagename):
00020         Page(request, pagename).send_page()
00021         return
00022 
00023     try:
00024         date = request.values['date']
00025         try:
00026             date = long(date) # must be long for py 2.2.x
00027         except StandardError:
00028             date = 0
00029     except KeyError:
00030         date = 0
00031 
00032     try:
00033         rev1 = int(request.values.get('rev1', -1))
00034     except StandardError:
00035         rev1 = 0
00036     try:
00037         rev2 = int(request.values.get('rev2', 0))
00038     except StandardError:
00039         rev2 = 0
00040 
00041     if rev1 == -1 and rev2 == 0:
00042         rev1 = request.rev
00043         if rev1 is None:
00044             rev1 = -1
00045 
00046     # spacing flag?
00047     ignorews = int(request.values.get('ignorews', 0))
00048 
00049     _ = request.getText
00050 
00051     # get a list of old revisions, and back out if none are available
00052     currentpage = Page(request, pagename)
00053     currentrev = currentpage.current_rev()
00054     if currentrev < 2:
00055         request.theme.add_msg(_("No older revisions available!"), "error")
00056         currentpage.send_page()
00057         return
00058 
00059     if date: # this is how we get called from RecentChanges
00060         rev1 = 0
00061         log = editlog.EditLog(request, rootpagename=pagename)
00062         for line in log.reverse():
00063             if date >= line.ed_time_usecs and int(line.rev) != 99999999:
00064                 rev1 = int(line.rev)
00065                 break
00066         else:
00067             rev1 = 1
00068         rev2 = 0
00069 
00070     # Start output
00071     # This action generates content in the user language
00072     request.setContentLanguage(request.lang)
00073 
00074     request.theme.send_title(_('Diff for "%s"') % (pagename, ), pagename=pagename, allow_doubleclick=1)
00075 
00076     if rev1 > 0 and rev2 > 0 and rev1 > rev2 or rev1 == 0 and rev2 > 0:
00077         rev1, rev2 = rev2, rev1
00078 
00079     if rev1 == -1:
00080         oldrev = currentrev - 1
00081         oldpage = Page(request, pagename, rev=oldrev)
00082     elif rev1 == 0:
00083         oldrev = currentrev
00084         oldpage = currentpage
00085     else:
00086         oldrev = rev1
00087         oldpage = Page(request, pagename, rev=oldrev)
00088 
00089     if rev2 == 0:
00090         newrev = currentrev
00091         newpage = currentpage
00092     else:
00093         newrev = rev2
00094         newpage = Page(request, pagename, rev=newrev)
00095 
00096     edit_count = abs(newrev - oldrev)
00097 
00098     f = request.formatter
00099     request.write(f.div(1, id="content"))
00100 
00101     oldrev = oldpage.get_real_rev()
00102     newrev = newpage.get_real_rev()
00103 
00104     revlist = currentpage.getRevList()
00105 
00106     # code below assumes that the page exists and has at least
00107     # one revision in the revlist, just bail out if not. Users
00108     # shouldn't really run into this anyway.
00109     if not revlist:
00110         request.write(f.div(0)) # end content div
00111         request.theme.send_footer(pagename)
00112         request.theme.send_closing_html()
00113         return
00114 
00115     title = _('Differences between revisions %d and %d') % (oldrev, newrev)
00116     if edit_count > 1:
00117         title += ' ' + _('(spanning %d versions)') % (edit_count, )
00118     title = f.text(title)
00119 
00120     # Revision list starts from 2...
00121     if oldrev <= min(revlist):
00122         disable_prev = u' disabled="disabled"'
00123     else:
00124         disable_prev = u''
00125 
00126     if newrev >= max(revlist):
00127         disable_next = u' disabled="disabled"'
00128     else:
00129         disable_next = u''
00130 
00131     page_url = wikiutil.escape(currentpage.url(request), True)
00132 
00133     revert_html = ""
00134     if request.user.may.revert(pagename):
00135         revert_html = """
00136  <td style="border:0">
00137   <form action="%s" method="get">
00138    <div style="text-align:center">
00139     <input name="action" value="revert" type="hidden">
00140     <input name="rev" value="%d" type="hidden">
00141     <input value="%s" type="submit"%s>
00142    </div>
00143   </form>
00144  </td>
00145  """ % (page_url, rev2, _("Revert to this revision"), disable_next)
00146 
00147     navigation_html = """
00148 <span class="diff-header">%s</span>
00149 <table class="diff">
00150 <tr>
00151  <td style="border:0">
00152   <form action="%s" method="get">
00153    <div style="text-align:left">
00154     <input name="action" value="diff" type="hidden">
00155     <input name="rev1" value="%d" type="hidden">
00156     <input name="rev2" value="%d" type="hidden">
00157     <input value="%s" type="submit"%s>
00158    </div>
00159   </form>
00160  </td>
00161  %s
00162  <td style="border:0">
00163   <form action="%s" method="get">
00164    <div style="text-align:right">
00165     <input name="action" value="diff" type="hidden">
00166     <input name="rev1" value="%d" type="hidden">
00167     <input name="rev2" value="%d" type="hidden">
00168     <input value="%s" type="submit"%s>
00169    </div>
00170   </form>
00171  </td>
00172 </tr>
00173 </table>
00174 """ % (title,
00175        page_url, oldrev - 1, oldrev, _("Previous change"), disable_prev,
00176        revert_html,
00177        page_url, newrev, newrev + 1, _("Next change"), disable_next, )
00178 
00179     request.write(f.rawHTML(navigation_html))
00180 
00181     if request.user.show_fancy_diff:
00182         from MoinMoin.util import diff_html
00183         request.write(f.rawHTML(diff_html.diff(request, oldpage.get_raw_body(), newpage.get_raw_body())))
00184         newpage.send_page(count_hit=0, content_only=1, content_id="content-below-diff")
00185     else:
00186         from MoinMoin.util import diff_text
00187         lines = diff_text.diff(oldpage.getlines(), newpage.getlines())
00188         if not lines:
00189             msg = f.text(" - " + _("No differences found!"))
00190             if edit_count > 1:
00191                 msg = msg + f.paragraph(1) + f.text(_('The page was saved %(count)d times, though!') % {
00192                     'count': edit_count}) + f.paragraph(0)
00193             request.write(msg)
00194         else:
00195             if ignorews:
00196                 request.write(f.text(_('(ignoring whitespace)')), f.linebreak())
00197             else:
00198                 qstr = {'action': 'diff', 'ignorews': '1', }
00199                 if rev1:
00200                     qstr['rev1'] = str(rev1)
00201                 if rev2:
00202                     qstr['rev2'] = str(rev2)
00203                 request.write(f.paragraph(1), Page(request, pagename).link_to(request,
00204                     text=_('Ignore changes in the amount of whitespace'),
00205                     querystr=qstr, rel='nofollow'), f.paragraph(0))
00206 
00207             request.write(f.preformatted(1))
00208             for line in lines:
00209                 if line[0] == "@":
00210                     request.write(f.rule(1))
00211                 request.write(f.text(line + '\n'))
00212             request.write(f.preformatted(0))
00213 
00214     request.write(f.div(0)) # end content div
00215     request.theme.send_footer(pagename)
00216     request.theme.send_closing_html()
00217