Extract filling project list info, i.e. adding age, description, owner and forks information, to fill_project_list_info() subroutine. This is preparation for smart pagination and smart searching (if possible, only calculate info for those projects which are shown). Extract generating table header cell one can sort by into print_sort_th_str() and print_sort_th_num() subroutines, and print_sort_th() driver subroutine. This avoids repetition, and should make further improvements (like JavaScript client-side sorting) easier. Signed-off-by: Jakub Narebski <jnareb@xxxxxxxxx> --- This is an RFC patch, first patch of series meant to improve generating list of projects, trying to reduce both amount of work server has to do to generate the page, and the size of the page to reduce amount of data send and amount of rendering web browser (client) has to do. An RFC because: * I don't quote like naming of print_sort_th*() subroutines, but I could not think of a better name * I wonder if there is a better way to pass arguments, and better way to deal with numeric sorting (age) and lexical soering (the rest). I'd like for someone with better Perl knowledge than me examine this patch. What is planned: * Adding description to project_list format, so everything except age (last changed) can be read by parsing single file, making gitweb performance better * Paginate projects list in such way so the information such as age is gathered and filled only for projects which are shown, if possible (it is not possible for example if worting by age) * Add searching for projects, by project name (project path), description, and owner. Make gitweb use search page if number of projects is greater than some configurable number, as a front page What is planned in the future * Add project's categories support. gitweb/gitweb.perl | 108 ++++++++++++++++++++++++++++----------------------- 1 files changed, 59 insertions(+), 49 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 2facf2d..6a28dca 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3548,21 +3548,23 @@ sub git_patchset_body { # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -sub git_project_list_body { - my ($projlist, $order, $from, $to, $extra, $no_header) = @_; - - my ($check_forks) = gitweb_check_feature('forks'); - +# fills project list info (age, description, owner, forks) for each +# project in the list, removing invalid projects from returned list +sub fill_project_list_info { + my ($projlist, $check_forks) = @_; my @projects; + + PROJECT: foreach my $pr (@$projlist) { - my (@aa) = git_get_last_activity($pr->{'path'}); - unless (@aa) { - next; + my (@activity) = git_get_last_activity($pr->{'path'}); + unless (@activity) { + next PROJECT; } - ($pr->{'age'}, $pr->{'age_string'}) = @aa; + ($pr->{'age'}, $pr->{'age_string'}) = @activity; if (!defined $pr->{'descr'}) { my $descr = git_get_project_description($pr->{'path'}) || ""; - $pr->{'descr_long'} = to_utf8($descr); + $descr = to_utf8($descr); + $pr->{'descr_long'} = $descr; $pr->{'descr'} = chop_str($descr, $projects_list_description_width, 5); } if (!defined $pr->{'owner'}) { @@ -3574,14 +3576,50 @@ sub git_project_list_body { ($pname !~ /\/$/) && (-d "$projectroot/$pname")) { $pr->{'forks'} = "-d $projectroot/$pname"; - } - else { + } else { $pr->{'forks'} = 0; } } push @projects, $pr; } + return @projects; +} + +sub print_sort_th { + my ($str_sort, $name, $order, $key, $header, $projlist) = @_; + $key ||= $name; + $header ||= ucfirst($name); + + if ($order eq $name) { + if ($str_sort) { + @$projlist = sort {$a->{$key} cmp $b->{$key}} @$projlist; + } else { + @$projlist = sort {$a->{$key} <=> $b->{$key}} @$projlist; + } + print "<th>$header</th>\n"; + } else { + print "<th>" . + $cgi->a({-href => href(project=>undef, order=>$name), + -class => "header"}, $header) . + "</th>\n"; + } +} + +sub print_sort_th_str { + print_sort_th(1, @_); +} + +sub print_sort_th_num { + print_sort_th(0, @_); +} + +sub git_project_list_body { + my ($projlist, $order, $from, $to, $extra, $no_header) = @_; + + my ($check_forks) = gitweb_check_feature('forks'); + my @projects = fill_project_list_info($projlist, $check_forks); + $order ||= $default_projects_order; $from = 0 unless defined $from; $to = $#projects if (!defined $to || $#projects < $to); @@ -3592,43 +3630,15 @@ sub git_project_list_body { if ($check_forks) { print "<th></th>\n"; } - if ($order eq "project") { - @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; - print "<th>Project</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'project'), - -class => "header"}, "Project") . - "</th>\n"; - } - if ($order eq "descr") { - @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; - print "<th>Description</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'descr'), - -class => "header"}, "Description") . - "</th>\n"; - } - if ($order eq "owner") { - @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; - print "<th>Owner</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'owner'), - -class => "header"}, "Owner") . - "</th>\n"; - } - if ($order eq "age") { - @projects = sort {$a->{'age'} <=> $b->{'age'}} @projects; - print "<th>Last Change</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'age'), - -class => "header"}, "Last Change") . - "</th>\n"; - } - print "<th></th>\n" . + print_sort_th_str('project', $order, 'path', + 'Project', \@projects); + print_sort_th_str('descr', $order, 'descr_long', + 'Description', \@projects); + print_sort_th_str('owner', $order, 'owner', + 'Owner', \@projects); + print_sort_th_num('age', $order, 'age', + 'Last Change', \@projects); + print "<th></th>\n" . # for links "</tr>\n"; } my $alternate = 1; -- 1.5.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html