3
# IVLE - Informatics Virtual Learning Environment
4
# Copyright (C) 2007-2008 The University of Melbourne
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
# A CGI script for generating a diff report page in HTML. It is intended to be
25
# run from the trampoline by the Diff application.
27
from common import cgirequest
33
def htmlfy_diff(difftext):
34
"""Adds HTML markup to a udiff string"""
35
output = cgi.escape(difftext)
36
match_file = re.compile(r'^([\+\-]{3})\s(\S+)\s\((.+)\)$',re.MULTILINE)
37
match_range = re.compile(r'^\@\@ (.*) \@\@$',re.MULTILINE)
38
match_add = re.compile(r'^\+(.*)$',re.MULTILINE)
39
match_sub = re.compile(r'^\-(.*)$',re.MULTILINE)
40
match_special = re.compile(r'^\\(.*)$',re.MULTILINE)
41
output = match_file.sub(
42
r'<span class="diff-files">\1 \2 <em>(\3)</em></span>', output)
43
output = match_range.sub(
44
r'<span class="diff-range">@@ \1 @@</span>', output)
45
output = match_add.sub(
46
r'<span class="diff-add">+\1</span>', output)
47
output = match_sub.sub(
48
r'<span class="diff-sub">-\1</span>', output)
49
output = match_special.sub(
50
r'<span class="diff-special">\\\1</span>', output)
53
def get_revision(r_str):
54
""" Returns a Revison object for pysvn from a r query string """
56
return pysvn.Revision( pysvn.opt_revision_kind.head )
57
elif r_str == "WORKING":
58
return pysvn.Revision( pysvn.opt_revision_kind.working )
60
return pysvn.Revision( pysvn.opt_revision_kind.base )
64
return pysvn.Revision( pysvn.opt_revision_kind.number, r)
68
# Use a CGIRequest object to make the CGI environment look like the normal
69
# IVLE handler environment.
71
req = cgirequest.CGIRequest()
72
req.content_type = "text/html"
74
# Beginning of the page
75
req.write('<div id="ivle_padding">\n')
76
req.write('<h1>Diff</h1>\n')
79
revs = [pysvn.Revision(x) for x in [pysvn.opt_revision_kind.base,
80
pysvn.opt_revision_kind.working]]
81
# Override revisions from query string
82
fields = req.get_fieldstorage()
83
field_r = fields.getlist("r")
84
for ri in range(len(field_r)):
85
r = get_revision(field_r[ri])
89
# Attempt to get the diff for these revisons
91
svnclient = pysvn.Client()
93
diff_text = diff( '/tmp/svndiff',
94
os.path.join('/home', req.path),
99
# Split up the udiff into individual files
100
diff_matcher = re.compile(
101
r'^Index: (.*)\n\=+\n((?:[^I].*\n)*)',re.MULTILINE
103
split_diff = diff_matcher.findall(diff_text)
106
for filediff in split_diff:
107
filename = filediff[0]
108
diffbody = htmlfy_diff(filediff[1])
109
req.write('<p><b>File:</b> %s</p>\n'
110
% cgi.escape(filename))
111
req.write('<pre class="diff">%s</pre>\n' % diffbody)
113
except pysvn._pysvn_2_5.ClientError, e:
114
req.write('<p><b>Error:</b></p>\n')
115
req.write('<pre class="diff">%s</pre>\n' % cgi.escape(str(e)))
117
req.write('</div>\n')