Rev 1295 | Blame | Compare with Previous | Last modification | View Log | RSS feed
################################################################################ Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.# sits@users.sourceforge.net## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Action object for displaying a list of topics.package Codestriker::Action::ListTopics;use strict;use Codestriker::Http::Template;use Codestriker::Model::Topic;# If the input is valid, list the appropriate topics.sub process($$$) {my ($type, $http_input, $http_response) = @_;my $query = $http_response->get_query();# Check if this action is allowed.if ($Codestriker::allow_searchlist == 0) {$http_response->error("This function has been disabled");}# Obtain a new URL builder object.my $url_builder = Codestriker::Http::UrlBuilder->new($query);my $mode = $http_input->get('mode');my $feedback = $http_input->get('feedback');my $projectid = $http_input->get('projectid');my ( $sauthor, $sreviewer, $scc, $sbugid,$sstate, $sproject, $stext,$stitle, $sdescription,$scomments, $sbody, $sfilename,$sort_order) = get_topic_list_query_params($http_input);# Query the model for the specified data.my @topics = Codestriker::Model::Topic->query($sauthor, $sreviewer, $scc, $sbugid,$sstate, $sproject, $stext,$stitle, $sdescription,$scomments, $sbody, $sfilename,$sort_order);# Display the data, with each topic title linked to the view topic screen.# If only a single project id is being searched over, set that id in the# cookie.my @project_ids = ();if ($sproject ne "") {@project_ids = split ',', $sproject;}my $projectid_cookie = ($#project_ids == 0) ? $project_ids[0] : "";$http_response->generate_header(topic_title=>"Topic List",projectid=>$projectid_cookie,topicsort=>join(',',@$sort_order),reload=>0, cache=>0);# Create the hash for the template variables.my $vars = {};$vars->{'feedback'} = $feedback;# Store the search parameters, which become hidden fields.$vars->{'sauthor'} = $sauthor;$vars->{'sreviewer'} = $sreviewer;$vars->{'scc'} = $scc;$vars->{'sbugid'} = $sbugid;$vars->{'stext'} = $stext;$vars->{'sstate'} = $sstate;$vars->{'stitle'} = $stitle;$vars->{'sdescription'} = $sdescription;$vars->{'scomments'} = $scomments;$vars->{'sbody'} = $sbody;$vars->{'sfilename'} = $sfilename;# Collect the comment metric counts that they want to show on the main page.my @comment_metric_names;foreach my $comment_state_metric (@{$Codestriker::comment_state_metrics}) {if (exists($comment_state_metric->{show_on_mainpage})) {foreach my $value (@{$comment_state_metric->{show_on_mainpage}}) {push @comment_metric_names,{ name => $comment_state_metric->{name},value => $value };}}}$vars->{'commentmetrics'} = \@comment_metric_names;# The url generated here includes all of the search parameters, so# that the current list of topics the user it viewing does not# revert back to the default open topic list. The search is# applied each time they change the sort order.$vars->{'list_sort_url'} =$url_builder->list_topics_url($sauthor, $sreviewer, $scc, $sbugid,$stext, $stitle,$sdescription, $scomments,$sbody, $sfilename,[ split ',', $sstate] , \@project_ids);$vars->{'list_sort_url_rss'} =$url_builder->list_topics_url_rss($sauthor, $sreviewer, $scc, $sbugid,$stext, $stitle,$sdescription, $scomments,$sbody, $sfilename,[ split ',', $sstate] , \@project_ids);# The list of topics in the template toolkit.my @template_topics;# For each topic, collect all the reviewers, CC, and bugs, and display it# as a row in the table. Each bug should be linked appropriately.foreach my $topic (@topics) {# do the easy stuff first, 1 to 1 mapping into the template.my $template_topic = {};$template_topic->{'view_topic_url'} =$url_builder->view_url($topic->{topicid}, -1, $mode,$Codestriker::default_topic_br_mode);$template_topic->{'description'} = $topic->{description};$template_topic->{'created'} =Codestriker->format_short_timestamp($topic->{creation_ts});$template_topic->{'id'} = $topic->{topicid};$template_topic->{'title'} = $topic->{title};$template_topic->{'version'} = $topic->{version};$template_topic->{'state'} = $Codestriker::topic_states[$topic->{topic_state_id}];# Only include the username part of the email address to save space.my $accum_author = $topic->{author};$accum_author =~ s/\@.*$//o;$template_topic->{'author'} = $accum_author;# ccmy $cc = $topic->{cc};$cc =~ s/\@.*$//o;$template_topic->{'cc'} = $cc;# bug idsmy @accum_bugs = split /, /, $topic->{bug_ids};for ( my $index = 0; $index < scalar(@accum_bugs); ++$index) {$accum_bugs[$index] =$query->a({href=>"$Codestriker::bugtracker$accum_bugs[$index]"},$accum_bugs[$index]);}$template_topic->{'bugids'} = join ', ', @accum_bugs;# do the reviewersmy @reviewers_vistited =$topic->get_metrics()->get_list_of_actual_topic_participants();my @reviewers = split /, /, $topic->{reviewers};for ( my $index = 0; $index < scalar(@reviewers); ++$index) {my $reviewer = $reviewers[$index];my $is_visted = 0;foreach my $visted (@reviewers_vistited) {if ($visted eq $reviewer) {$is_visted = 1;last;}}# Output the accumulated information into the row. Only# include the username part of an email address for now to# save some space. This should be made a dynamic option# in the future.$reviewer =~ s/\@.*$//o;if ( $is_visted == 0) {$reviewer = "(" . $reviewer . ")";}$reviewers[$index] = $reviewer;}$template_topic->{'reviewer'} = join(", ",@reviewers);my @main_page_comment_metrics = ();foreach my $comment_state_metric (@{$Codestriker::comment_state_metrics}) {if ( exists($comment_state_metric->{show_on_mainpage})) {foreach my $value (@{$comment_state_metric->{show_on_mainpage}}) {my $count = $topic->get_comment_metric_count($comment_state_metric->{name},$value);my $template_comment_metric ={name => $comment_state_metric->{name},value => $value,count => $count};push @main_page_comment_metrics,$template_comment_metric;}}}$template_topic->{'commentmetrics'} = \@main_page_comment_metrics;push @template_topics, $template_topic;}$vars->{'topics'} = \@template_topics;$vars->{'states'} = \@Codestriker::topic_states;$vars->{'list_projects_url'} = $url_builder->list_projects_url();$vars->{'view_metrics_url'} = $url_builder->metric_report_url();my $template = Codestriker::Http::Template->new("listtopics");$template->process($vars);$http_response->generate_footer();}# Process the input and return the parts that will feed into the topic# list query. Returns in the same order that the topic query function# takes them.sub get_topic_list_query_params {my ($http_input) = @_;# Check that the appropriate fields have been filled in.my $sauthor = $http_input->get('sauthor') || "";my $sreviewer = $http_input->get('sreviewer') || "";my $scc = $http_input->get('scc') || "";my $sbugid = $http_input->get('sbugid') || "";my $stext = $http_input->get('stext') || "";my $sstate = $http_input->get('sstate');my $sproject = $http_input->get('sproject');my $stitle = $http_input->get('stitle') || 0;my $sdescription = $http_input->get('sdescription') || 0;my $scomments = $http_input->get('scomments') || 0;my $sbody = $http_input->get('sbody') || 0;my $sfilename = $http_input->get('sfilename') || 0;my $projectid = $http_input->get('projectid');# If $sproject has been set to -1, then retrieve the value of the projectid# from the cookie as the project search value. This is done to facilate# integration with other systems, which jump straight to this URL, and# set the cookie explicitly.if ($sproject eq "-1") {$sproject = (defined $projectid) ? $projectid : "";}# Only show open topics if codestriker.pl was run without parameters.if (defined($http_input->{query}->param) == 0 || !defined($sstate)) {$sstate = join(',', @Codestriker::default_states_indexes);}# handle the sort order of the topics.my @sort_order = get_topic_sort_order($http_input);return ( $sauthor, $sreviewer, $scc, $sbugid,$sstate, $sproject, $stext,$stitle, $sdescription,$scomments, $sbody, $sfilename,\@sort_order);}# Process the topic_sort_change input request (if any), and the current sort# cookie (topicsort), and returns a list that defines the topic sort order# that should be used for this request. The function will ensure that# column types are not repeated, and will sort in the opposite direction# if the user clicks on the same column twice.sub get_topic_sort_order {my ($http_input) = @_;my $topic_sort_change = $http_input->get('topic_sort_change');my $topicsort = $http_input->get('topicsort');my @sort_order = split(/,/,$topicsort); # this is always from the cookie.if ($topic_sort_change ne "") {if (scalar(@sort_order) > 0) {# If the user clicked on the same column twice in a row, reverse# the direction of the sort.$sort_order[0] =~ s/\+$topic_sort_change/\-$topic_sort_change/ or$sort_order[0] =~ s/\-$topic_sort_change/\+$topic_sort_change/ orunshift @sort_order, "+" . $topic_sort_change;}else {unshift @sort_order, "+" . $topic_sort_change;}# look for duplicate sort keys, and removemy %sort_hash;for ( my $index = 0;$index < scalar( @sort_order);# Incremented in the if...) {# chew off the leading +-my $current = $sort_order[$index];if ($current =~ s/^[\+\-]//) {if (exists $sort_hash{$current}) {# remove from the list.splice @sort_order, $index,1;}else {# have not seem this before, keep it, and look at the next# string.++$index;}$sort_hash{$current} = 1;}}}# Pull out any elements that are not valid (from a bad cookie or from a bad# input.for (my $index = 0; $index < scalar(@sort_order) ; ++$index) {if ($sort_order[$index] ne "+title" && $sort_order[$index] ne "-title" &&$sort_order[$index] ne "+author" && $sort_order[$index] ne "-author" &&$sort_order[$index] ne "+created" && $sort_order[$index] ne "-created" &&$sort_order[$index] ne "+state" && $sort_order[$index] ne "-state") {splice @sort_order,$index,1;--$index;}}return @sort_order;}1;