| 1293 |
dpurdie |
1 |
###############################################################################
|
|
|
2 |
# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
|
|
|
3 |
# sits@users.sourceforge.net
|
|
|
4 |
#
|
|
|
5 |
# This program is free software; you can redistribute it and modify it under
|
|
|
6 |
# the terms of the GPL.
|
|
|
7 |
|
|
|
8 |
# Action object for handling the submission of a new comment.
|
|
|
9 |
|
|
|
10 |
package Codestriker::Action::SubmitNewComment;
|
|
|
11 |
|
|
|
12 |
use strict;
|
|
|
13 |
|
|
|
14 |
use HTML::Entities ();
|
|
|
15 |
use Codestriker::Model::Comment;
|
|
|
16 |
use Codestriker::Model::File;
|
|
|
17 |
use Codestriker::Model::Topic;
|
|
|
18 |
use Codestriker::Http::Render;
|
|
|
19 |
|
|
|
20 |
# If the input is valid, create the appropriate topic into the database.
|
|
|
21 |
sub process($$$) {
|
|
|
22 |
my ($type, $http_input, $http_response) = @_;
|
|
|
23 |
|
|
|
24 |
# Obtain a new URL builder object.
|
|
|
25 |
my $query = $http_response->get_query();
|
|
|
26 |
my $url_builder = Codestriker::Http::UrlBuilder->new($query);
|
|
|
27 |
|
|
|
28 |
# Check that the appropriate fields have been filled in.
|
|
|
29 |
my $topicid = $http_input->get('topic');
|
|
|
30 |
my $line = $http_input->get('line');
|
|
|
31 |
my $fn = $http_input->get('fn');
|
|
|
32 |
my $new = $http_input->get('new');
|
|
|
33 |
my $comments = $http_input->get('comments');
|
|
|
34 |
my $email = $http_input->get('email');
|
|
|
35 |
my $cc = $http_input->get('comment_cc');
|
|
|
36 |
my $mode = $http_input->get('mode');
|
|
|
37 |
my $anchor = $http_input->get('a');
|
|
|
38 |
my $format = $http_input->get('format');
|
|
|
39 |
|
|
|
40 |
# Check that the fields have been filled appropriately.
|
|
|
41 |
if ($comments eq "" || !defined $comments) {
|
|
|
42 |
$http_response->error("No comments were entered");
|
|
|
43 |
}
|
|
|
44 |
if ($email eq "" || !defined $email) {
|
|
|
45 |
$http_response->error("No email address was entered");
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
# Retrieve the comment metric values.
|
|
|
49 |
my @metrics = ();
|
|
|
50 |
foreach my $comment_state_metric (@{$Codestriker::comment_state_metrics}) {
|
|
|
51 |
my $name = "comment_state_metric_" . $comment_state_metric->{name};
|
|
|
52 |
my $metric = {};
|
|
|
53 |
$metric->{name} = $comment_state_metric->{name};
|
|
|
54 |
$metric->{value} = $http_input->get($name);
|
|
|
55 |
if ($metric->{value} eq "Select Value") {
|
|
|
56 |
$http_response->error("Metric value for $metric->{name} unspecified");
|
|
|
57 |
}
|
|
|
58 |
push @metrics, $metric;
|
|
|
59 |
}
|
|
|
60 |
|
|
|
61 |
# Retrieve the appropriate topic details.
|
|
|
62 |
my $topic = Codestriker::Model::Topic->new($topicid);
|
|
|
63 |
|
|
|
64 |
# Don't accept any new comments if the topic state is read only.
|
|
|
65 |
if (Codestriker::topic_readonly($topic->{topic_state})) {
|
|
|
66 |
$http_response->error("Topic state is read only");
|
|
|
67 |
}
|
|
|
68 |
|
|
|
69 |
# Fire the topic listener to indicate that the user has viewed the topic.
|
|
|
70 |
Codestriker::TopicListeners::Manager::topic_viewed($email, $topic);
|
|
|
71 |
|
|
|
72 |
# Create the comment in the database.
|
|
|
73 |
my $comment = Codestriker::Model::Comment->new();
|
|
|
74 |
$comment->create($topicid, $line, $fn, $new,
|
|
|
75 |
$email, $comments, \@metrics);
|
|
|
76 |
$comment->{cc} = $cc;
|
|
|
77 |
|
|
|
78 |
# Tell the listener classes that a comment has just been created.
|
|
|
79 |
my $listener_response =
|
|
|
80 |
Codestriker::TopicListeners::Manager::comment_create($topic, $comment);
|
|
|
81 |
|
|
|
82 |
if (defined $format && $format eq "xml") {
|
|
|
83 |
my $response = $listener_response ne '' ? $listener_response : 'OK';
|
|
|
84 |
|
|
|
85 |
print $query->header(-content_type=>'text/xml');
|
|
|
86 |
print "<?xml version=\"1.0\" encoding=\"UTF-8\" " .
|
|
|
87 |
"standalone=\"yes\"?>\n";
|
|
|
88 |
print "<response><method>submitnewcomment</method>" .
|
|
|
89 |
"<result>" . HTML::Entities::encode($response) .
|
|
|
90 |
"</result></response>\n";
|
|
|
91 |
} else {
|
|
|
92 |
$http_response->error($listener_response) if $listener_response ne '';
|
|
|
93 |
# Display a simple screen indicating that the comment has been
|
|
|
94 |
# registered. Clicking the Close button simply dismisses the
|
|
|
95 |
# edit popup. Leaving it # up will ensure the next editing
|
|
|
96 |
# topic will be handled quickly, as the # overhead of bringing
|
|
|
97 |
# up a new window is removed.
|
|
|
98 |
my $reload = $query->param('submit') eq 'Submit+Refresh' ? 1 : 0;
|
|
|
99 |
$http_response->generate_header(topic=>$topic,
|
|
|
100 |
topic_title=>"Comment Submitted: " .
|
|
|
101 |
"$topic->{title}",
|
|
|
102 |
email=>$email,
|
|
|
103 |
repository=>$Codestriker::repository_name_map->{$topic->{repository}},
|
|
|
104 |
load_anchor=>$anchor,
|
|
|
105 |
reload=>$reload, cache=>0);
|
|
|
106 |
|
|
|
107 |
my $view_topic_url = $url_builder->view_url($topicid, $line, $mode);
|
|
|
108 |
my $view_comments_url = $url_builder->view_comments_url($topicid);
|
|
|
109 |
|
|
|
110 |
my $vars = {};
|
|
|
111 |
$vars->{'view_topic_url'} = $view_topic_url;
|
|
|
112 |
$vars->{'view_comments_url'} = $view_comments_url;
|
|
|
113 |
$vars->{'comment'} = $comment->{data};
|
|
|
114 |
|
|
|
115 |
my $template = Codestriker::Http::Template->new("submitnewcomment");
|
|
|
116 |
$template->process($vars);
|
|
|
117 |
|
|
|
118 |
$http_response->generate_footer();
|
|
|
119 |
}
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
# Given a topic and topic line number, try to determine the line
|
|
|
123 |
# number of the new file it corresponds to. For topic lines which
|
|
|
124 |
# were made against '+' lines or unchanged lines, this will give an
|
|
|
125 |
# accurate result. For other situations, the number returned will be
|
|
|
126 |
# approximate. The results are returned in $filename_ref,
|
|
|
127 |
# $linenumber_ref and $accurate_ref references. This is a deprecated method
|
|
|
128 |
# which is only used for data migration purposes (within checksetup.pl and
|
|
|
129 |
# import.pl).
|
|
|
130 |
sub _get_file_linenumber ($$$$$$$$)
|
|
|
131 |
{
|
|
|
132 |
my ($type, $topic, $topic_linenumber, $filenumber_ref,
|
|
|
133 |
$filename_ref, $linenumber_ref, $accurate_ref, $new_ref) = @_;
|
|
|
134 |
|
|
|
135 |
# Find the appropriate file that $topic_linenumber refers to.
|
|
|
136 |
my (@filename, @revision, @offset, @binary);
|
|
|
137 |
Codestriker::Model::File->get_filetable($topic, \@filename, \@revision,
|
|
|
138 |
\@offset, \@binary);
|
|
|
139 |
# No filetable.
|
|
|
140 |
return 0 if ($#filename == -1);
|
|
|
141 |
|
|
|
142 |
my $diff_limit = -1;
|
|
|
143 |
my $index;
|
|
|
144 |
for ($index = 0; $index <= $#filename; $index++) {
|
|
|
145 |
last if ($offset[$index] > $topic_linenumber);
|
|
|
146 |
}
|
|
|
147 |
|
|
|
148 |
# Check if the comment was made against a diff header.
|
|
|
149 |
if ($index <= $#offset) {
|
|
|
150 |
my $diff_header_size;
|
|
|
151 |
if ($revision[$index] eq $Codestriker::ADDED_REVISION ||
|
|
|
152 |
$revision[$index] eq $Codestriker::REMOVED_REVISION) {
|
|
|
153 |
# Added or removed file.
|
|
|
154 |
$diff_header_size = 6;
|
|
|
155 |
}
|
|
|
156 |
elsif ($revision[$index] eq $Codestriker::PATCH_REVISION) {
|
|
|
157 |
# Patch file
|
|
|
158 |
$diff_header_size = 3;
|
|
|
159 |
}
|
|
|
160 |
else {
|
|
|
161 |
# Normal CVS diff header.
|
|
|
162 |
$diff_header_size = 7;
|
|
|
163 |
}
|
|
|
164 |
|
|
|
165 |
if ( ($topic_linenumber >=
|
|
|
166 |
$offset[$index] - $diff_header_size) &&
|
|
|
167 |
($topic_linenumber <= $offset[$index]) ) {
|
|
|
168 |
$$filenumber_ref = $index;
|
|
|
169 |
$$filename_ref = $filename[$index];
|
|
|
170 |
$$linenumber_ref = 1;
|
|
|
171 |
$$accurate_ref = 0;
|
|
|
172 |
$$new_ref = 0;
|
|
|
173 |
return 1;
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
$index--;
|
|
|
177 |
|
|
|
178 |
# Couldn't find a matching linenumber.
|
|
|
179 |
if ($index < 0 || $index > $#filename) {
|
|
|
180 |
$$filenumber_ref = -1;
|
|
|
181 |
$$filename_ref = "";
|
|
|
182 |
return 1;
|
|
|
183 |
}
|
|
|
184 |
|
|
|
185 |
# Retrieve the diff text corresponding to this file.
|
|
|
186 |
my ($tmp_offset, $tmp_revision, $diff_text);
|
|
|
187 |
Codestriker::Model::File->get($topic, $index, \$tmp_offset,
|
|
|
188 |
\$tmp_revision, \$diff_text);
|
|
|
189 |
|
|
|
190 |
# Go through the patch file until we reach the topic linenumber of
|
|
|
191 |
# interest.
|
|
|
192 |
my $new = 0;
|
|
|
193 |
my $accurate_line = 0;
|
|
|
194 |
my $oldfile_linenumber = 0;
|
|
|
195 |
my $newfile_linenumber = 0;
|
|
|
196 |
my $current_topic_linenumber;
|
|
|
197 |
my @lines = split /\n/, $diff_text;
|
|
|
198 |
for (my $i = 0, $current_topic_linenumber = $offset[$index];
|
|
|
199 |
$i <= $#lines && $current_topic_linenumber <= $topic_linenumber;
|
|
|
200 |
$i++, $current_topic_linenumber++) {
|
|
|
201 |
$_ = $lines[$i];
|
|
|
202 |
if (/^\@\@ \-(\d+),\d+ \+(\d+),\d+ \@\@.*$/o) {
|
|
|
203 |
# Matching diff header, record what the current linenumber is now
|
|
|
204 |
# in the new file.
|
|
|
205 |
$oldfile_linenumber = $1 - 1;
|
|
|
206 |
$newfile_linenumber = $2 - 1;
|
|
|
207 |
$accurate_line = 0;
|
|
|
208 |
$new = 0;
|
|
|
209 |
}
|
|
|
210 |
elsif (/^\s.*$/o) {
|
|
|
211 |
# A line with no change.
|
|
|
212 |
$oldfile_linenumber++;
|
|
|
213 |
$newfile_linenumber++;
|
|
|
214 |
$accurate_line = 1;
|
|
|
215 |
$new = 1;
|
|
|
216 |
}
|
|
|
217 |
elsif (/^\+.*$/o) {
|
|
|
218 |
# A line corresponding to the new file.
|
|
|
219 |
$newfile_linenumber++;
|
|
|
220 |
$accurate_line = 1;
|
|
|
221 |
$new = 1;
|
|
|
222 |
}
|
|
|
223 |
elsif (/^\-.*$/o) {
|
|
|
224 |
# A line corresponding to the old file.
|
|
|
225 |
$oldfile_linenumber++;
|
|
|
226 |
$accurate_line = 0;
|
|
|
227 |
$new = 0;
|
|
|
228 |
}
|
|
|
229 |
}
|
|
|
230 |
|
|
|
231 |
if ($current_topic_linenumber >= $topic_linenumber) {
|
|
|
232 |
# The topic linenumber was found.
|
|
|
233 |
$$filenumber_ref = $index;
|
|
|
234 |
$$filename_ref = $filename[$index];
|
|
|
235 |
$$linenumber_ref = $new ? $newfile_linenumber : $oldfile_linenumber;
|
|
|
236 |
$$accurate_ref = $accurate_line;
|
|
|
237 |
$$new_ref = $new;
|
|
|
238 |
}
|
|
|
239 |
else {
|
|
|
240 |
# The topic linenumber was not found.
|
|
|
241 |
$$filenumber_ref = -1;
|
|
|
242 |
$$filename_ref = "";
|
|
|
243 |
}
|
|
|
244 |
return 1;
|
|
|
245 |
}
|
|
|
246 |
|
|
|
247 |
1;
|