]> git.deb.at Git - deb/packages.git/blob - cgi-bin/dispatcher.pl
Fix contents search my moving it to lib, like the rest. Still a bit rough.
[deb/packages.git] / cgi-bin / dispatcher.pl
1 #!/usr/bin/perl -T
2 # $Id: search_packages.pl 91 2006-02-10 22:18:31Z jeroen $
3 # dispatcher.pl -- CGI interface for packages.debian.org
4 #
5 # Copyright (C) 2004-2006 Frank Lichtenheld
6 #
7 # use is allowed under the terms of the GNU Public License (GPL)                              
8 # see http://www.fsf.org/copyleft/gpl.html for a copy of the license
9
10 use strict;
11 use warnings;
12
13 use lib '../lib';
14 use CGI;
15 use POSIX;
16 use URI::Escape;
17 use HTML::Entities;
18 use DB_File;
19 use Benchmark;
20
21 use Deb::Versions;
22 use Packages::Config qw( $DBDIR $ROOT $SEARCH_CGI $SEARCH_PAGE
23                          @SUITES @SECTIONS @ARCHIVES @ARCHITECTURES );
24 use Packages::CGI;
25 use Packages::DB;
26 use Packages::Search qw( :all );
27 use Packages::HTML ();
28 use Packages::Sections;
29
30 use Packages::DoSearch;
31 use Packages::DoSearchContents;
32 use Packages::DoShow;
33 use Packages::DoDownload;
34 use Packages::DoFilelist;
35
36 &Packages::CGI::reset;
37
38 $ENV{PATH} = "/bin:/usr/bin";
39
40 # Read in all the variables set by the form
41 my $input;
42 if ($ARGV[0] && ($ARGV[0] eq 'php')) {
43         $input = new CGI(\*STDIN);
44 } else {
45         $input = new CGI;
46 }
47
48 my $pet0 = new Benchmark;
49 my $tet0 = new Benchmark;
50 # use this to disable debugging in production mode completly
51 my $debug_allowed = 1;
52 my $debug = $debug_allowed && $input->param("debug");
53 $debug = 0 if !defined($debug) || $debug !~ /^\d+$/o;
54 $Packages::CGI::debug = $debug;
55
56 &Packages::Config::init( '../' );
57 &Packages::DB::init();
58
59 my $what_to_do = 'show';
60 my $source = 0;
61 if (my $path = $input->path_info() || $input->param('PATH_INFO')) {
62     my @components = grep { $_ } map { lc $_ } split /\/+/, $path;
63
64     debug( "components[0]=$components[0]", 2 );
65     if ($components[0] eq 'search') {
66         shift @components;
67         $what_to_do = 'search';
68     }
69     if ($components[0] eq 'source') {
70         shift @components;
71         $input->param( 'source', 1 );
72     }
73     if (@components == 0) {
74         # we just hope we get the information through our parameters...
75     } elsif (@components == 1) {
76         $what_to_do = 'search';
77     } else {
78
79         for ($components[-1]) {
80             /^(changelog|copyright|download|filelist)$/ && do {
81                 pop @components;
82                 $what_to_do = $1;
83                 last;
84             };
85         }
86
87         my %SUITES = map { $_ => 1 } @SUITES;
88         my %SUITES_ALIAS = ( woody => 'oldstable',
89                              sarge => 'stable',
90                              etch => 'testing',
91                              sid => 'unstable', );
92         my %SECTIONS = map { $_ => 1 } @SECTIONS;
93         my %ARCHIVES = map { $_ => 1 } @ARCHIVES;
94         my %ARCHITECTURES = map { $_ => 1 } (@ARCHITECTURES, 'all');
95         my %params_set;
96         sub set_param_once {
97             my ($cgi, $params_set, $key, $val) = @_;
98             if ($params_set->{$key}++) {
99                 fatal_error( "$key set more than once in path" );
100             } else {
101                 $cgi->param( $key, $val );
102             }
103         }
104
105         my @tmp;
106         foreach (@components) {
107             if ($SUITES{$_}) {
108                 set_param_once( $input, \%params_set, 'suite', $_);
109 #possible conflicts with package names
110 #           } elsif (my $s = $SUITES_ALIAS{$_}) {
111 #               set_param_once( $input, \%params_set, 'suite', $s);
112             } elsif ($SECTIONS{$_}) {
113                 set_param_once( $input, \%params_set, 'section', $_);
114             } elsif ($ARCHIVES{$_}) {
115                 set_param_once( $input, \%params_set, 'archive', $_);
116             } elsif ($ARCHITECTURES{$_}) {
117                 set_param_once( $input, \%params_set, 'arch', $_);
118             } elsif ($sections_descs{$_}) {
119                 set_param_once( $input, \%params_set, 'subsection', $_);
120             } elsif ($_ eq 'source') {
121                 set_param_once( $input, \%params_set, 'source', 1);
122             } else {
123                 push @tmp, $_;
124             }
125         }
126         @components = @tmp;
127
128         if (@components > 1) {
129             fatal_error( "two or more packages specified (@components)" );
130         }
131     } # else if (@components == 1)
132     
133     if (@components) {
134         $input->param( 'keywords', $components[0] );
135         $input->param( 'package', $components[0] );
136     }
137 }
138
139 my ( $pkg, @suites, @sections, @subsections, @archives, @archs );
140
141 my %params_def = ( keywords => { default => undef,
142                                  match => '^\s*([-+\@\s\w\/.:]+)\s*$',
143                              },
144                    package => { default => undef,
145                                 match => '^([\w.+-]+)$',
146                                 var => \$pkg },
147                    suite => { default => 'all', match => '^([\w-]+)$',
148                               array => ',', var => \@suites,
149                               replace => { all => \@SUITES } },
150                    archive => { default => ($what_to_do eq 'search') ?
151                                     'all' : 'default',
152                                     match => '^([\w-]+)$',
153                                     array => ',', var => \@archives,
154                                     replace => { all => \@ARCHIVES,
155                                              default => [qw(us security non-US)]} },
156                    exact => { default => 0, match => '^(\w+)$',  },
157                    source => { default => 0, match => '^(\d+)$',  },
158                    searchon => { default => 'names', match => '^(\w+)$', },
159                    section => { default => 'all', match => '^([\w-]+)$',
160                                 alias => 'release', array => ',',
161                                 var => \@sections,
162                                 replace => { all => \@SECTIONS } },
163                    subsection => { default => 'default', match => '^([\w-]+)$',
164                                    array => ',', var => \@subsections,
165                                    replace => { default => [] } },
166                    arch => { default => 'any', match => '^(\w+)$',
167                              array => ',', var => \@archs, replace =>
168                              { any => \@ARCHITECTURES } },
169                    );
170 my %opts;
171 my %params = Packages::Search::parse_params( $input, \%params_def, \%opts );
172
173 $opts{h_suites} = { map { $_ => 1 } @suites };
174 $opts{h_sections} = { map { $_ => 1 } @sections };
175 $opts{h_archives} = { map { $_ => 1 } @archives };
176 $opts{h_archs} = { map { $_ => 1 } @archs };
177
178 if ((($opts{searchon} eq 'names') && $opts{source}) ||
179     ($opts{searchon} eq 'sourcenames')) {
180     $opts{source} = 1;
181     $opts{searchon} = 'names',
182     $opts{searchon_form} = 'sourcenames';
183 } else {
184     $opts{searchon_form} = $opts{searchon};
185 }
186 if ($opts{searchon} eq 'contents' or $opts{searchon} eq 'filenames') {
187     $what_to_do = 'search_contents';
188 }
189
190 my $pet1 = new Benchmark;
191 my $petd = timediff($pet1, $pet0);
192 debug( "Parameter evaluation took ".timestr($petd) );
193
194 print $input->header( -charset => 'utf-8' );
195
196 my (%html_header, $menu, $page_content);
197 unless (@Packages::CGI::fatal_errors) {
198     no strict 'refs';
199     &{"do_$what_to_do"}( \%params, \%opts, \%html_header,
200                          \$menu, \$page_content );
201 } else {
202     %html_header = ( title => 'Error',
203                      lang => 'en',
204                      print_title => 1,
205                      print_search_field => 'packages',
206                      search_field_values => { 
207                          keywords => 'search for a package',
208                          searchon => 'default',
209                          arch => 'any',
210                          suite => 'all',
211                          section => 'all',
212                          exact => 1,
213                          debug => $debug,
214                      },
215                      );
216 }
217
218 print Packages::HTML::header( %html_header );
219
220 print $menu||'';
221 print_errors();
222 print_hints();
223 print_msgs();
224 print_debug();
225 print_notes();
226
227 unless (@Packages::CGI::fatal_errors) {
228     print $page_content;
229 }
230
231 my $tet1 = new Benchmark;
232 my $tetd = timediff($tet1, $tet0);
233 print "Total page evaluation took ".timestr($tetd)."<br>"
234     if $debug_allowed;
235
236 my $trailer = Packages::HTML::trailer( $ROOT );
237 $trailer =~ s/LAST_MODIFIED_DATE/gmtime()/e; #FIXME
238 print $trailer;
239
240 # vim: ts=8 sw=4
241