urgent multi-draft fixes from amalfi
[stet:stet.git] / rtNoAuth / tweakcustom.html
1 %# Copyright (C) 2005, 2006   Software Freedom Law Center, Inc.
2 %# Author: Orion Montoya <orion@mdcclv.com>
3 %#
4 %# This software gives you freedom; it is licensed to you under version
5 %# 3 of the GNU Affero General Public License, along with the
6 %# additional permission in the following paragraph.
7 %#
8 %# This notice constitutes a grant of such permission as is necessary
9 %# to combine or link this software, or a modified version of it, with
10 %# Request Tracker (RT), published by Jesse Vincent and Best Practical
11 %# Solutions, LLC, or a derivative work of RT, and to copy, modify, and
12 %# distribute the resulting work.  RT is licensed under version 2 of
13 %# the GNU General Public License.
14 %# 
15 %# This software is distributed WITHOUT ANY WARRANTY, without even the
16 %# implied warranties of MERCHANTABILITY and FITNESS FOR A PARTICULAR
17 %# PURPOSE.  See the GNU Affero General Public License for further
18 %# details.
19 %#  
20 %# You should have received a copy of the GNU Affero General Public
21 %# License, version 3, and the GNU General Public License, version 2,
22 %# along with this software.  If not, see <http://www.gnu.org/licenses/>.
23 %
24 % sub displayTicket($$$);
25 %
26 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
27 <html>
28 <head>
29 <title>read GPLv3 comments: <% humanQuery($ARGS{'Query'}) || $ARGS{'id'} %></title>
30 <link rel="stylesheet" type="text/css" href="/comments/stet.css" />
31 <script type="text/javascript" src="/comments/prototype.js"></script>
32 <script type="text/javascript">
33 function hideall(class) {
34 var sc = document.getElementsByClassName(class);
35 sc.length.times(function(n) {
36 Element.hide(sc[n]);
37 });
38
39 }
40 function showall(class) {
41 var sc = document.getElementsByClassName(class);
42 sc.length.times(function(n) {
43 Element.show(sc[n]);
44 });
45 }
46 function togExp(el) {
47 if (el.innerHTML.indexOf('collapse') != -1) {
48 el.innerHTML = "expand children";
49 el.setAttribute('onclick',"showall('child'); togExp(this); return false;");
50 }
51 else {
52 el.innerHTML = "collapse children";
53 el.setAttribute('onclick',"hideall('child'); togExp(this); return false;");
54 }
55 }
56 </script>
57 </head>
58 <body>
59 <div id="topbar" class="topbar">
60 <span id="statustext" class="statustext">
61 % if ($Tickets) {
62 Showing comments <% humanQuery($ARGS{'Query'}) |n %> <a class="rsslink" href="<% $rsslink %>">[rss]</a> <a href="/comments/<% stripCrap($Tickets->First->FirstCustomFieldValue('NoteUrl')) %>?Query=<% $ARGS{'Query'} %>">[see on license]</a> <br/> 
63 ( found <% $Tickets->CountAll()%>, showing newest <% $StartAt %>-<% (($StartAt + $Rows) > $Tickets->CountAll()) ? $Tickets->CountAll() : ($StartAt + $Rows - 1) %>:
64 %   if ($Tickets->CountAll() > $Rows) {
65 %       if ($StartAt > 1 ) {
66       <a href="/comments/rt/readsay.html?Query=<% $ARGS{'Query'} |n %>&amp;Rows=<%$Rows%>&amp;StartAt=<% (($StartAt - $Rows) < 0) ? 1 : ($StartAt - $Rows) |n%>">prev <% $Rows %></a>
67 %       }
68 %   if (($Tickets->CountAll() > $Rows) && ($Tickets->CountAll() < $StartAt + $Rows)) {
69 |
70 %   }
71 %   if ($Tickets->CountAll() > $StartAt + $Rows) {
72          <a href="/comments/rt/readsay.html?Query=<% $ARGS{'Query'} |n %>&amp;Rows=<%$Rows%>&amp;StartAt=<% $StartAt + $Rows %>">next <% $Rows %></a>
73 %   }
74 %}
75 )
76 <a href="/comments/rt/changeshown.html?came_from=rt/readsay.html">search</a> 
77 <%perl> 
78     $Tickets->GotoFirstItem;
79     if ($StartAt > 1) {
80         for (my $i = 0; $i < $StartAt; $i++) {
81             $Tickets->Next;
82         }
83     }
84 </%perl>
85 % } elsif ($Ticket) {
86 Showing comment <a href="/comments/rt/readsay.html?id=<% $ARGS{'id'} %>"><% $ARGS{'id'} %></a> <a class="rsslink" href="<% $rsslink %>">[rss]</a> <a href="/comments/<% stripCrap($Ticket->FirstCustomFieldValue('NoteUrl')) %>?id=<% $ARGS{'id'} %>#<% $ARGS{'id'} %>">[see on license]</a> <a href="/comments/rt/changeshown.html?came_from=<% stripCrap($Ticket->FirstCustomFieldValue('NoteUrl')) %>">search</a>
87 % }
88 % if ($name) {
89 </span><span id="login" class="login">you are <% $name %>: <a href="http://gplv3.fsf.org/logout">logout</a></span></div>
90 % } else {
91 </span><span id="login" class="login">you could <a href="http://gplv3.fsf.org/login_form?came_from=/comments/rt/readsay.html?<% $Tickets ? 'Query='.$ARGS{'Query'} : 'id='.$ARGS{'id'} %>">login</a></span></div>
92 % }
93 <& header.html, name => $name &>
94 <div id="readsaymain">
95 <span id="listactions">
96 <& Elements/ListActions, actions => \@results &>
97 </span>
98 %
99 % while (my $item = $Tickets ? $Tickets->Next : $Ticket) {
100 % my $showactions = $Tickets ? 0 : 1;
101 <% displayTicket(\$item,$showactions,0) %>
102 % $Ticket = '';
103 % $rc++;
104 % if ($rc == (($StartAt + $Rows) - 1)) {
105 %    $Tickets = '';
106 % } 
107 % }
108 <!-- <div id="bottombar"><a href="stet-latest.tar.gz">get the latest source code for this comment system</a></div> -->
109 %
110 % sub displayTicket($$$) {
111 % my $itemref = shift;
112 % my $item = $$itemref;
113 % my $showactions = shift;
114 % my $deletelink = shift;
115 % if (!$deletelink) {
116 %  if ($resp == 1) {
117     <form action="readsay-devel.html" method="POST" name="TicketUpdate" enctype="multipart/form-data">
118        <input type="hidden" name="id" value="<% $item->id %>">
119 %  }
120 % }
121
122 % if ($item->QueueObj->CurrentUserHasRight('SeeQueue')) {
123  <div class="onecomment<% ($item->QueueObj->Name =~ /Drafter/) && " Drafter" %><% $deletelink && " child\" id=\"child".$item->id |n %>">
124   <h4><% ($item->QueueObj->Name =~ /Drafter/) && " Drafter's " %><% thingType(\$item) %> <a href="readsay.html?id=<% $item->id %>"><% $item->id %>: <% $item->Subject %></a>
125 %  if ($item->Queue == $fsfqueue) {
126 <div class="admin">This issue has been escalated to the Drafters <!-- by fixme --> </div>
127 %  }
128 %      if (($HasIssueRights) && ($showactions) && ($deletelink)) {
129             <span class="TktInput">[dissociate: <INPUT TYPE=CHECKBOX NAME="<% $deletelink %>" value="1">]</span>
130 %      }
131 </h4>
132 % if (!$deletelink) {
133 %   while (my $link = $item->MemberOf->Next) {
134     <span class="formHelpIsh">This <% thingType(\$item) %> is part of the discussion  on:<br/> #<& Elements/ShowLink, URI => $link->TargetURI, StetId => $link->id  &></span><span class="TktInput">
135 %
136 %      if ($HasIssueRights == 1) {
137            <span class="TktInput">[dissociate from parent: <INPUT TYPE=CHECKBOX NAME="DeleteLink--<% $link->Type %>-<% $link->Target %>" value="1">]</span>
138 %      }
139        <br/>
140 % }
141
142 %   }
143 <br/>
144   <span class="formHelpIsh">Regarding the text:</span> <span class="ontextText"><q><% $scrubber->scrub($item->FirstCustomFieldValue('NoteSelection')) %></q></span><br/>
145     <span class="formHelpIsh">In section: <span class="nodeLink"><a href="/comments/rt/readsay.html?Query=%20'CF.NoteStartNodeId'%20LIKE%20'<% $scrubber->scrub($item->FirstCustomFieldValue('NoteStartNodeId')) %>'%20AND%20'CF.NoteUrl'%20LIKE%20'<%stripCrap($item->FirstCustomFieldValue('NoteUrl'))%>'%20"><% $scrubber->scrub($item->FirstCustomFieldValue('NoteStartNodeId')) %></a></span></span><br/>
146 %#    In section: <span class="nodeLink"><a href="/comments/<%stripCrap($item->FirstCustomFieldValue('NoteUrl'))%>?Query=%20'CF.NoteStartNodeId'%20LIKE%20'<% $scrubber->scrub($item->FirstCustomFieldValue('NoteStartNodeId')) %>'%20AND%20'CF.NoteUrl'%20LIKE%20'<%stripCrap($item->FirstCustomFieldValue('NoteUrl'))%>'%20"><% $scrubber->scrub($item->FirstCustomFieldValue('NoteStartNodeId')) %></a></span><br/>
147   <span class="formHelpIsh">Submitted by: <% userlink(\$item, \$item) |n%> <span class="date">on <% doDate(\$item) %></span></span><br/>
148 <% listAgree(\$item) %>
149 %# my ($agrees,$agr_count) = showAgree(\$item);
150 %# print STDERR "agree is $agree\n";
151 %#  <% $agree |n %><br/>
152 %#  <span class="agreecount"><% $agr_count %> agree</span></span><br/>
153 %#  comments:<br/> 
154 <br/>
155 <% getThread(\$item) |n %>
156 <br/><strong><a href="#" onclick="hideall('child'); togExp(this); return false;">collapse children</a></strong><br> 
157
158 %   if ($item->Members->GotoFirstItem) {
159         <em>this <% thingType(\$item) %> does not have any children </em><br/>
160 %   }
161 <br/>
162 %   while (my $link = $item->Members->Next) {
163     <span class="TktLabel">Child comment of <% $item->id %>: <a href="#" onclick="javascript:Element.toggle(document.getElementById('child<% $link->BaseURI->Object->id %>'));return false;"><% $link->BaseURI->Object->id %>: <% $link->BaseURI->Object->Subject %> &plusmn;</a></span><br/>
164 %    my $child = RT::Ticket->new($CurrentUser);
165 %    $child->Load($link->BaseURI->Object->id);
166 % my $deletelink = "DeleteLink-". $link->Base ."-". $link->Type."-";
167 <% displayTicket(\$child,$showactions,$deletelink) %>
168 %   }
169 <br/>
170 %  if (($HasIssueRights) && ($showactions) && (!$deletelink)) {
171 <br/>
172   <span class="TktLabel">Children:</span><br/>
173         <span class="TktInput indent">add new: <INPUT NAME="MemberOf-<% $item->id %>"> <span class="inputcaption">[comment id numbers, space separated]</span></span>
174 %  }
175 % if (($showactions) & (!$deletelink)){
176 <br/>
177 %  if ($HasIssueRights) {
178     <span class="TktLabel">Parents:</span><br/>
179        <span class="TktInput indent">add new: <INPUT NAME="<% $item->id %>-MemberOf"> <span class="inputcaption">[comment id numbers, space separated]</span></span>
180 %  }
181     <br/>
182     <span class="TktLabel">Links:</span>
183 %   if ($item->RefersTo->GotoFirstItem) {
184         <em>this <% thingType(\$item) %> does not link to any external resources</em>
185 %   }
186  <br/>
187 %   while (my $link = $item->RefersTo->Next) {
188         <A HREF="<% $link->Target %>"><% $link->Target %></A>
189 %       if ($HasIssueRights) {
190             <span class="TktInput">[delete: <INPUT TYPE=CHECKBOX NAME="DeleteLink--<% $link->Base %>-<% $link->Type %>" value="1">]</span>
191 %           }
192  <br/>
193 %   }
194 %
195 %  if ($HasIssueRights) {
196         <span class="TktInput indent">link to external item(s): <INPUT NAME="<% $item->id %>-RefersTo"> <span class="inputcaption">[URIs with protocol://, space separated]</span></span><br/>
197 %  }
198
199 %     my $DiscussGrpObj = RT::CustomField->new($CurrentUser);
200 %     $DiscussGrpObj->Load(8);
201 %     our $Values  = $item->CustomFieldValues($DiscussGrpObj->id);
202 %     our $GroupNames = $DiscussGrpObj->Values();
203  <br>
204     <span class="TktLabel">Current Committees:</span>
205 % while (my $Committee = $GroupNames->Next) {
206     <% $Values->HasEntry($Committee->Name) && $Committee->Name %>
207 %    }
208  <br>
209 %####  customfield picker doesn't show which groups are related
210 %  if ($HasIssueRights) {
211 %  my $groupRows = 7;
212  <span class="groupselect"><span class="TktLabel select">Change Committees:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
213  <br>
214       <input type="hidden" name="Ticket-<% $item->id %>-CustomField-<%$DiscussGrpObj->Id%>-Values-Magic" value="1">
215       <span class="TktInput indent"><select name="Ticket-<% $item->id %>-CustomField-<%$DiscussGrpObj->Id%>-Values"
216         size="<%$groupRows%>"
217         <%$DiscussGrpObj->Type eq 'SelectMultiple' && 'MULTIPLE'%>>
218 %       my $CustomFieldValues = $DiscussGrpObj->Values();
219 %       my $selected;
220 %       while (my $value = $CustomFieldValues->Next) {
221         <option value="<%$value->Name%>"
222 %       if ($item) {
223             <% $Values->HasEntry($value->Name) && ($selected = 1) && 'SELECTED' %>
224 %       } 
225             ><% $value->Name%></option>
226 %           }
227         <option value="" <% !$selected && 'SELECTED' %>><&|/l&>(no value)</&></option>
228       </select><br/></span>
229 %
230 %  if (($HasIssueRights) && ($item->Queue != ($issuequeue || $fsfqueue ))) {
231        <input type="checkbox" value="1" name="MakeIssue"/><span class="TktLabel"> Upgrade this Comment to an Issue</span><br/>
232
233 %  }
234 %  if (($HasIssueRights) && ($item->Queue == ($issuequeue || $fsfqueue))) {
235 <div class="admin box">
236        <input type="radio" value="Escalated" name="ChangeQueue"/><span class="TktLabel"> Escalate this for FSF review (intentionally hard to undo)</span><br/>
237     <input type="radio" value="Inbox" name="ChangeQueue"/><span class="TktLabel"> Downgrade this Issue to a Comment</span></div>
238 %  }
239 % if ($item->OwnerObj->Name =~ "Nobody") {
240  <input type="checkbox" name="Take" value="Take"> <span class="TktLabel">Take personal ownership of this ticket</span><br/>
241 % }
242 % } 
243 % if ($item->OwnerObj->Name !~ "Nobody") {
244     <span class="TktLabel">This ticket is owned by</span> <% $item->OwnerObj->Name eq $name ? "<em>you</em>" : $item->OwnerObj->Name |n %>
245 %# of Committee <% $item->OwnerObj->Organization %>
246 % if (($HasIssueRights) && ($item->OwnerObj->Name != $name)) {
247             <input type="checkbox" name="Steal" value="Steal"> steal
248 % } 
249 % elsif (($HasIssueRights) && ($item->OwnerObj->Name =~ $name)) {
250         <input type="checkbox" name="Untake" value="Untake"> disown
251 % }
252 % }
253  <br>
254 %  if ($resp == 1) {
255         <input type=hidden name="UpdateType" value="public">
256         <span class="TktLabel">Add comments:</span> <br/>
257         <textarea class="messagebox" COLS=72 ROWS=15 WRAP=HARD NAME="UpdateContent" onfocus="if(this.value=='Enter additional comments here') {this.value='';}" onblur="if(this.value==''){this.value='Enter additional comments here';}"></textarea><br/>
258 %      if ($HasIssueRights) {
259              <INPUT TYPE=SUBMIT NAME="SubmitTicket" VALUE="Make changes"></form>
260 %      } else {
261            <INPUT TYPE=SUBMIT NAME="SubmitTicket" VALUE="Add comment"></form>
262 %      }
263 %  } # should close "if $resp == 1" after picker
264 % }
265  </div>
266 % }
267 % else {
268 <div class="onecomment formHelpIsh">You do not have permission to view comment number <% $item->id %><br/> <br/></div>
269
270 % }
271 % return '';
272 % }
273 </body>
274 </html>
275 <%INIT>
276 use CGI qw/:standard/;
277 use HTML::Scrubber;
278 our $scrubber = HTML::Scrubber->new( allow => [ qw[ a b i u br ] ] );
279 require "/var/www/stet/stetsubs.pl";
280 our $issuequeue = 5; 
281 our $fsfqueue = 6;
282 my $rc = 0;
283 our ($name, $resp, $CurrentUser, $HasIssueRights);
284 my ($pass, $agr_vals, $thing);
285 ($CurrentUser, $resp, $name) = getUser("foo");
286 $CurrentUser = $session{'CurrentUser'};
287
288 my $rsslink = "/comments/rt/rssresults.rdf?id=".$ARGS{'id'}."&Query=".$ARGS{'Query'};
289
290 my ($Tickets, $Ticket, @results, @msgresults, @linkresults, @cfresults);
291
292
293 if ($ARGS{'Query'}) {
294     $Tickets = RT::Tickets->new($CurrentUser);
295     $Tickets->FromSQL($ARGS{'Query'});
296     $Tickets->OrderBy( FIELD => 'id', ORDER => $ARGS{'Order'});
297 }
298 elsif ($ARGS{'id'}) {
299     $Ticket = RT::Ticket->new($CurrentUser);
300     $Ticket = LoadTicket($ARGS{'id'});
301     if ($ARGS{'SubmitTicket'}) {
302         ProcessUpdateMessage(TicketObj => $Ticket, ARGSRef=>\%ARGS, Actions=>\@msgresults);
303         @linkresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
304         @cfresults = ProcessTicketCustomFieldUpdates(TicketObj => $Ticket, ARGSRef => \%ARGS);
305         $ARGS{'Take'} && ($Ticket->Take()); # && print STDERR $CurrentUser->Name." taking ticket ".$Ticket->id."\n");
306         $ARGS{'Steal'} && ($Ticket->Steal()); # && print STDERR $CurrentUser->Name." stealing ticket ".$Ticket->id."\n");
307         $ARGS{'Untake'} && ($Ticket->Untake()); # && print STDERR $CurrentUser->Name." untaking ticket ".$Ticket->id."\n");
308    }
309     if ($ARGS{'MakeIssue'}) {
310         $Ticket->SetQueue($issuequeue);
311     }
312     if ($ARGS{'ChangeQueue'}) {
313         $Ticket->SetQueue($ARGS{'ChangeQueue'});
314     }
315
316     foreach my $result (@msgresults,@linkresults,@cfresults) {
317         push @results,$result;
318     }
319 }
320
321 my $NewQueueObj = RT::Queue->new( $CurrentUser );
322 $NewQueueObj->Load($issuequeue); 
323
324 if (
325     (
326         $CurrentUser->HasRight(
327             Right    => 'CreateTicket',
328             Object => $NewQueueObj
329         )
330       )
331 )
332     {
333         $HasIssueRights = 1;
334     }
335 else {$HasIssueRights = '';}
336
337 sub thingType($) {
338     my $itemref = shift;
339     my $item = $$itemref;
340 if ($item->Queue == 5) {
341     return "Issue";
342 }
343 elsif ($item->Queue == 6) {
344     return "Escalated Issue";
345 }
346 else {
347     return "Comment";
348 }
349 }
350
351
352
353 sub getThread($) {
354
355     my $itemref = shift;
356     my $item = $$itemref;
357     my $Transactions = $item->Transactions;
358     my $allcomments = '';
359     my $scrubber = HTML::Scrubber->new( allow => [ qw[ a b i u br ] ] );
360     while (my $Transaction = $Transactions->Next) {
361         
362         if ($Transaction->Type =~ /^(Create|Correspond|Comment$)/) {
363             
364             my $attachments = $Transaction->Attachments;
365 #    my $CustomFields = $item->QueueObj->TicketCustomFields();
366             my $CustomFields = $item->QueueObj->CustomFields();
367             $attachments->GotoFirstItem;
368             while (my $message = $attachments->Next) {
369 #                        $allcomments .= $Transaction->Content;
370                 my ($subj, $cont) = ('');
371                 if ($message->Subject != '') {
372                     $subj = $scrubber->scrub($message->Subject);
373                 }
374                 #$cont = sprintf("%s",$message->Content);
375                 #        if ($message->Content != '') {
376                 $cont = $scrubber->scrub($message->Content);
377                 if ($cont =~ s/(\S)\n\n(\S)/$1<\/p><p>\n$2/gs) {
378                 $cont = "<p>$cont</p>";
379             }
380                 $cont =~ s/&(?!amp;)/&amp;/g;
381                 #        }
382 #                        if ($cont = $message->Content) {
383 #                            $cont = $scrubber->scrub($cont);
384 #                        }
385                 
386                 $allcomments .= "<span class=\"formHelpIsh\">noted by ". userlink(\$item,\$message) ." <span class=\"date\">on ".doDate(\$message).":</span></span></span>\n";          
387                 $allcomments .= "<blockquote><h4>$subj</h4>\n".$cont."</blockquote>\n";
388
389 #           $allcomments .= "</blockquote>";
390             }
391         }
392             else {
393                 unless (($Transaction->CreatorObj->Name =~ "RT_System") || ($Transaction->BriefDescription =~ "NoteText|NoteSelection|NodeId|Agreeer")) {
394                
395                     $allcomments .= "<div class=\"formHelpIsh\">".$Transaction->BriefDescription." by ".userlink(\$item,\$Transaction)." <span class=\"date\">on ".doDate(\$Transaction)."</span></div>\n";
396                 }
397             }
398
399         }
400       
401             return $allcomments;
402         
403     }
404
405 sub userlink($$) {
406     my $itemref = shift;
407     my $item = $$itemref;
408     my $msgref = shift;
409     my $message = $$msgref;
410     return "<span class=\"userlink\"><a href=\"/comments/".$item->FirstCustomFieldValue('NoteUrl')."?Query=%20Requestor.Name%20LIKE%20'".$message->CreatorObj->Name."'%20AND%20'CF.NoteUrl'%20LIKE%20'".$item->FirstCustomFieldValue('NoteUrl')."'%20\">".$message->CreatorObj->Name."</a>". longOrg($message->CreatorObj)."</span>";
411 }
412
413 sub doDate($) {
414     my $itemref = shift;
415     my $item = $$itemref;
416     $item->Created =~ m/(\d\d\d\d-\d\d-\d\d) (\d\d:\d\d):\d\d/;
417     return  "$1 at $2 ". getTZ($item->Created);
418 }
419
420 sub getTZ($) {  # RT doesn't store dates with timezones.  
421 # this implementation is somehow wrong, though...
422 my $date = shift;
423 $date =~ s/\d\d\d\d-(\d\d)-\d\d.*/$1/;
424 my $eastern = "EST";
425 if ($date > 3) {  # after the end of March...
426     $eastern = "EDT";
427 }
428 if ($date > 10) {  # after the end of October...
429     $eastern = "EST";
430 }
431
432 return $eastern;
433 }
434
435 sub listAgree($) {
436     my $item = shift;
437     my $agr_vals;
438     my $showagree = ''; 
439     $agr_vals = $$item->CustomFieldValues(7);
440     while (my $value = $agr_vals->Next) {
441         $showagree .= $value->Content.", ";
442     }
443     $showagree =~ s/\n,/,/g;
444     $showagree =~ s/, $//g;
445     return $agr_vals->Count. " agree: ".$showagree;
446 }
447
448
449 </%INIT>
450 <%ARGS>
451 $Rows => 30
452 $StartAt => 1
453 $Order => 'DESC'
454 $Query => "'CF.NoteUrl' LIKE 'gplv3-draft-1'"
455 $Take => undef
456 $Steal => undef
457 $Untake => undef
458 </%ARGS>