source: server/trunk/web/lib/Sophie/Controller/Search.pm @ 148

Last change on this file since 148 was 148, checked in by nanardon, 13 years ago
  • cleanup the mess introduce by previous commit
  • factorize code
File size: 8.5 KB
Line 
1package Sophie::Controller::Search;
2use Moose;
3use namespace::autoclean;
4use Sophie;
5
6BEGIN {extends 'Catalyst::Controller'; }
7
8=head1 NAME
9
10Sophie::Controller::Search - Catalyst Controller
11
12=head1 DESCRIPTION
13
14Catalyst Controller.
15
16=head1 METHODS
17
18=cut
19
20
21=head2 index
22
23=cut
24
25sub index :Path :Args(0) {
26    my ($self, $c) = @_;
27
28    if ($c->req->param('page')) {
29        $c->req->params->{search} = $c->session->{search};
30        $c->req->params->{type} = $c->session->{type};
31        $c->req->params->{deptype} = $c->session->{deptype};
32    } else {
33        $c->session->{search} = $c->req->params->{search};
34        $c->session->{type} = $c->req->params->{type};
35        $c->session->{deptype} = $c->req->params->{deptype};
36    }
37
38    my $searchspec = {
39    };
40
41    for ($c->req->param('type')) {
42        /^byname$/ and do {
43            $c->stash->{sargs} = [ {}, $c->req->param('search') ];
44            $c->visit('/search/rpm/byname_rpc', [ $searchspec, $c->req->param('search') ||
45                    undef ]);
46            last;
47        };
48        /^bydep$/ and do {
49            my @args = ($c->req->param('deptype'), grep { $_ }
50                split(/\s+/, $c->req->param('search') || '' ));
51            $c->stash->{sargs} = [ {}, @args ],
52            $c->visit('/search/rpm/bydep_rpc', [ $searchspec, @args ]);
53            last;
54        };
55        /^byfile$/ and do {
56            my @args = ($c->req->param('search') || '');
57            $c->stash->{sargs} = [ {}, @args ],
58            $c->visit('/search/rpm/byfile_rpc', [ $searchspec, @args ]);
59            last;
60        };
61    }
62    #$c->forward('/search/rpm/end');
63}
64
65sub results :Local {
66    my ( $self, $c ) = @_;
67
68    if ($c->req->param('page')) {
69        $c->req->params->{search} ||= $c->session->{search};
70    }
71
72    if ($c->req->param('search')) {
73        $c->session->{search} = $c->req->param('search');
74        $c->visit('/search/rpm/quick', [
75                {
76                    src => 0,
77                } , grep { $_ } split(/\s/, $c->req->param('search')) ]);
78
79    }
80    $c->forward('/search/rpm/end');
81}
82
83sub adv_search :Local {
84    my ( $self, $c ) = @_;
85}
86
87sub distrib_search : Private {
88    my ( $self, $c, $searchspec, $asfilter ) = @_;
89
90    # if asfilter is set, return undef if nothing would have been filter
91    if (my $rs = $c->forward('/distrib/distrib_rs', [ $searchspec, $asfilter ]))
92    {
93        return $rs
94            ->search_related('MediasPaths')
95            ->search_related('Paths')
96            ->search_related('Rpmfiles');
97        } else {
98            return;
99        }
100}
101
102sub byname_rs : Private {
103    my ( $self, $c, $searchspec, $name, $sense, $evr ) = @_;
104    $searchspec ||= {};
105
106    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
107
108    return $c->model('Base::Rpms')->search(
109        {
110            -and => [ 
111                (exists($searchspec->{src})
112                    ? { issrc => $searchspec->{src} ? 1 : 0 }
113                    : ()),
114                { name => $name },
115                ( $evr
116                    ? { -nest => \[ 
117                        "rpmdepmatch(rpmsenseflag('='), evr, rpmsenseflag(?), ?)",
118                        [ plain_text => $sense],
119                        [ plain_text => $evr ],
120                    ] }
121                    : ()),
122                ($distrs
123                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, }, }
124                    : ()),
125            ]     
126        },
127        {
128                order_by => [ 'name', 'evr using >>', 'issrc' ],
129        }
130    );
131}
132
133sub bytag_rs : Private {
134    my ( $self, $c, $searchspec, $tag, $tagvalue ) = @_;
135    $searchspec ||= {};
136
137    my $tagrs = $c->model('Base')->resultset('Tags')
138        ->search({ tagname => lc($tag), value => $tagvalue})
139        ->get_column('pkgid');
140    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
141    return $c->model('Base')->resultset('Rpms')->search(
142        {
143            -and => [ 
144                (exists($searchspec->{src})
145                    ? { issrc => $searchspec->{src} ? 1 : 0 }
146                    : ()),
147                { pkgid => 
148                    { IN => $tagrs->as_query, },
149                },
150                $distrs
151                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, }, }
152                    : (),
153            ]     
154        },
155    );
156}
157
158sub bypkgid_rs : Private {
159    my ( $self, $c, $searchspec, $pkgid ) = @_;
160    $searchspec ||= {};
161
162    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
163
164    return $c->model('Base::Rpms')->search(
165        {
166            -and => [ 
167                (exists($searchspec->{src})
168                    ? { issrc => $searchspec->{src} ? 1 : 0 }
169                    : ()),
170                { pkgid => $pkgid },
171                $distrs
172                    ? { pkgid => { IN => $distrs->get_column('pkgid')->as_query, } }
173                    : ()
174            ]     
175        },
176    );
177}
178
179sub deps_rs : Private {
180    my ($self, $c, $searchspec, $deptype, $depname, $depsense, $depevr ) = @_;
181
182    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
183
184    return $c->model('Base::Deps')->search(
185        {
186            -and => [
187            { deptype => $deptype },
188            { depname => $depname },
189            ($depsense
190                ? ({-nest => \[
191                    'rpmdepmatch(flags, evr, rpmsenseflag(?), ?)',
192                    [ plain_text => $depsense],
193                    [ plain_text => $depevr ]
194                ]})
195            : ()),
196            ($distrs 
197                ? ({ pkgid => { IN => $distrs->get_column('pkgid')->as_query,
198                        },})
199                : ()),
200            (exists($searchspec->{src})
201                ? { pkgid => { IN => $c->model('Base::Rpms')->search(
202                            { issrc => $searchspec->{src} ? 1 : 0 }
203                        )->get_column('pkgid')->as_query, }, }
204                : ()),
205            ($searchspec->{pkgid}
206                ? { pkgid => $searchspec->{pkgid} }
207                : ()),
208            ]
209        },
210        {
211            '+select' => [ { rpmsenseflag => 'flags' }, 'depname', ],
212            '+as'     => [ qw(sense name) ],
213
214        }
215    );
216}
217
218sub file_rs : Private {
219    my ( $self, $c, $searchspec, $file) = @_;
220    my ($dirname, $basename) = $file =~ m:^(.*/)?([^/]+)$:;
221    $dirname =~ m:^[/]: or $dirname = undef;
222    if (!$dirname) {
223        if ($file =~ /(\*|\?)/) {
224            $file =~ tr/*?/%_/;
225        } else {
226            $file = '%' . $file;
227        }
228    }
229    $searchspec ||= {};
230
231    my $distrs = $c->forward('distrib_search', [ $searchspec, 1 ]);
232
233    return $c->model('Base::Files')->search(
234        {
235            -and => [
236                ($dirname
237                    ? (dirname => $dirname)
238                    : ()),
239                { 'dirname || basename' => { LIKE => $file } },
240                basename => $basename,
241                ($searchspec->{content} ? { has_content => 1 } : ()),
242                ($distrs 
243                    ? (pkgid => { IN => $distrs->get_column('pkgid')->as_query, },)
244                    : ()),
245                ($searchspec->{pkgid}
246                    ? { pkgid => $searchspec->{pkgid} }
247                    : ()),
248            ],
249        },
250        {
251            '+select' => [
252                'contents is NOT NULL as has_content',
253                { rpmfilesmode => 'mode' },
254            ],
255            '+as' => [ qw(has_content perm), ],
256        }
257    );
258}
259
260sub end : Private {
261    my ($self, $c, $searchspec) = @_;
262
263    if ($c->action =~ m:search/[^/]+/.:) {
264        my $rs = $c->stash->{rs}->search(
265            {},
266            {
267                page => $searchspec->{page} || 
268                     $c->req->param('page') || 1,
269                rows => $searchspec->{rows} || 
270                     $c->req->param('rows') || 10,
271            },
272        );
273
274        $c->stash->{rs} = $rs;
275        my @results = map { { $_->get_columns } } $rs->all;
276
277        $c->stash->{xmlrpc} = {};
278        if (!$searchspec->{nopager}) {
279            my $pager = $c->stash->{rs}->pager;
280            $c->stash->{pager} = $pager;
281            $c->stash->{xmlrpc} = {
282                    pages => $pager->last_page,
283                    current_page => $pager->current_page,
284                    total_entries => $pager->total_entries,
285                    entries_per_page => $pager->entries_per_page,
286            };
287        }
288        $c->stash->{xmlrpc}{results} = \@results;
289    } else {
290        $c->forward('/end');
291    }
292}
293
294=head1 AUTHOR
295
296Olivier Thauvin
297
298=head1 LICENSE
299
300This library is free software. You can redistribute it and/or modify
301it under the same terms as Perl itself.
302
303=cut
304
305__PACKAGE__->meta->make_immutable;
306
3071;
Note: See TracBrowser for help on using the repository browser.