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

Last change on this file since 55 was 55, checked in by nanardon, 14 years ago
  • rework search
File size: 9.1 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
29sub results :Local {
30    my ( $self, $c ) = @_;
31
32    if ($c->req->param('page')) {
33        $c->req->params->{search} ||= $c->session->{search};
34    }
35
36    if ($c->req->param('search')) {
37        $c->session->{search} = $c->req->param('search');
38        $c->forward('quick', [ undef, grep { $_ } split(/\s/, $c->req->param('search')) ]);
39        my $pager = $c->stash->{rs}->pager;
40        $c->stash->{pager} = $pager;
41        $c->stash->{xmlrpc} = {
42            results => [ $c->stash->{rs}->get_column('pkgid')->all ],
43            pages => $pager->last_page,
44            current_page => $pager->current_page,
45            total_entries => $pager->total_entries,
46            entries_per_page => $pager->entries_per_page,
47        };
48    }
49}
50
51sub search_param : Private {
52    my ($self, $c) = @_;
53    my $r = {
54        rows => Sophie->config()->{'max_reply'} || 20000,
55        order_by => [ 'name', 'evr using >>', 'issrc' ],
56        select => [ 'pkgid' ],
57    };
58    if (!$c->req->xmlrpc->method) {
59        $r->{page} = $c->req->param('page') || 1;
60        $r->{rows} = $c->req->param('rows') || 15;
61    }
62    return $r;
63}
64
65sub distrib_search : Private {
66    my ( $self, $c, $searchspec ) = @_;
67
68    return $c->forward('/distrib/distrib_rs', [ $searchspec ])
69        ->search_related('MediasPaths')
70        ->search_related('Paths')
71        ->search_related('Rpmfiles');
72}
73
74sub format_search : Private {
75    my ( $self, $c, $searchspec ) = @_;
76
77    my $rs = $c->stash->{rs}->search(
78        {},
79        {
80            page => $searchspec->{page} || 1,
81            rows => $searchspec->{rows} || 10,
82        },
83    );
84
85    if (!$searchspec->{page}) {
86        my $pager = $rs->pager;
87        $c->stash->{xmlrpc} = {
88                pages => $pager->last_page,
89                current_page => $pager->current_page,
90                total_entries => $pager->total_entries,
91                entries_per_page => $pager->entries_per_page,
92        };
93    }
94    $c->stash->{xmlrpc}{results} = [ $rs->get_column('pkgid')->all ];
95}
96
97sub bypkgid : XMLRPCPath('/search/rpm/bypkgid') {
98    my ( $self, $c, $searchspec, $pkgid ) = @_;
99
100    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
101        {
102            -and => [ 
103                (exists($searchspec->{src})
104                    ? { issrc => $searchspec->{src} ? 1 : 0 }
105                    : ()),
106                { pkgid => $pkgid }, 
107                { pkgid =>
108                    { IN => $c->forward('distrib_search', [ $searchspec
109                        ])->get_column('pkgid')->as_query, }, 
110                },
111            ]     
112        },
113    );
114
115    $c->forward('format_search', $searchspec);
116}
117
118sub bytag : XMLRPCPath('/search/rpm/bytag') {
119    my ( $self, $c, $searchspec, $tag, $tagvalue ) = @_;
120
121    my $tagrs = $c->model('Base')->resultset('Tags')
122        ->search({ tagname => lc($tag), value => $tagvalue})
123        ->get_column('pkgid');
124    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
125        {
126            -and => [ 
127                (exists($searchspec->{src})
128                    ? { issrc => $searchspec->{src} ? 1 : 0 }
129                    : ()),
130                { pkgid => 
131                    { IN => $tagrs->as_query, },
132                },
133                { pkgid =>
134                    { IN => $c->forward('distrib_search', [ $searchspec
135                        ])->get_column('pkgid')->as_query, }, 
136                },
137            ]     
138        },
139    );
140    $c->forward('format_search', $searchspec);
141
142}
143
144sub bydep : XMLRPCPath('/search/rpm/bydep') {
145    my ( $self, $c, $searchspec, $deptype, $depname, $depsense, $depevr ) = @_;
146
147    my $deprs = $c->model('Base')->resultset('Deps')->search(
148        {
149            deptype => $deptype,
150            depname => $depname,
151            ($depsense
152                ? (-nest => \[
153                    'rpmdepmatch(flags, evr, rpmsenseflag(?), ?)',
154                    [ plain_text => $depsense],
155                    [ plain_text => $depevr ]
156                ])
157            : ()),
158        }
159    )->get_column('pkgid');
160    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
161        {
162            -and => [ 
163                (exists($searchspec->{src})
164                    ? { issrc => $searchspec->{src} ? 1 : 0 }
165                    : ()),
166                { pkgid => 
167                    { IN => $deprs->as_query, },
168                },
169                { pkgid =>
170                    { IN => $c->forward('distrib_search', [ $searchspec
171                        ])->get_column('pkgid')->as_query, }, 
172                },
173            ]     
174        },
175    );
176    $c->forward('format_search', $searchspec);
177}
178
179sub byfile : XMLRPCPath('/search/rpm/byfile') {
180    my ( $self, $c, $searchspec, $file) = @_;
181    my ($dirname, $basename) = $file =~ m:^(.*/)?([^/]+)$:;
182
183    my $filers = $c->model('Base')->resultset('Files')
184    ->search({
185            ($dirname
186                ? (dirname => $dirname)
187                : ()),
188            basename => $basename,
189        })
190    ->get_column('pkgid');
191    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
192        {
193            -and => [ 
194                (exists($searchspec->{src})
195                    ? { issrc => $searchspec->{src} ? 1 : 0 }
196                    : ()),
197                { pkgid => 
198                    { IN => $filers->as_query, },
199                },
200                { pkgid =>
201                    { IN => $c->forward('distrib_search', [ $searchspec
202                        ])->get_column('pkgid')->as_query, }, 
203                },
204            ]     
205        },
206    );
207    $c->forward('format_search', $searchspec);
208}
209
210sub fuzzy : XMLRPCPath('/search/rpm/fuzzy') {
211    my ($self, $c, $searchspec, $name) = @_;
212
213    my $deprs = $c->model('Base')->resultset('Deps')->search(
214        { deptype => 'P', depname => { '~*' => $name } }
215    )->get_column('pkgid');
216
217    $c->stash->{rs} = 
218
219        $c->model('Base')->resultset('Rpms')->search(
220        {
221            -and => [
222                (exists($searchspec->{src})
223                    ? { issrc => $searchspec->{src} ? 1 : 0 }
224                    : ()),
225                { -or => [
226                    { name => 
227                        { '~*' => $name, },
228                    },
229#                    { pkgid =>
230#                        { IN => $deprs->as_query, },
231#                    },
232                     ]
233                },
234                { pkgid =>
235                    { IN => $c->forward('distrib_search', [ $searchspec
236                        ])->get_column('pkgid')->as_query, }, 
237                },
238            ]     
239        },
240        $c->forward('search_param'),
241    );
242   
243    $c->forward('format_search', $searchspec);
244}
245
246sub quick : XMLRPCPath('/search/rpm/quick') {
247    my ($self, $c, $searchspec, @keywords) = @_;
248    my $tsquery = join(' & ', map { $_ =~ s/ /\\ /g; $_ } @keywords);
249    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
250            {
251                -or => [
252                    { -nest => \[
253                        "to_tsvector('english', description) @@ to_tsquery(?)",
254                        [ plain_text => $tsquery],
255                    ], },
256                    {
257                    name => [ @keywords ],
258                    },
259                ],
260            (exists($searchspec->{src})
261                ? (issrc => $searchspec->{src} ? 1 : 0)
262                : ()),
263            pkgid =>
264            { IN => $c->forward('distrib_search', [ $searchspec
265                    ])->get_column('pkgid')->as_query, }, 
266
267
268        },
269        {
270            %{$c->forward('search_param')},
271        },
272    );
273    $c->forward('format_search', $searchspec);
274}
275
276sub description : XMLRPCPath('/search/rpm/description') {
277    my ($self, $c, $searchspec, @keywords) = @_;
278    my $tsquery = join(' & ', map { $_ =~ s/ /\\ /g; $_ } @keywords);
279    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
280        {
281            -nest => \[
282                    "to_tsvector('english', description) @@ to_tsquery(?)",
283                    [ plain_text => $tsquery],
284                ],
285                (exists($searchspec->{src})
286                    ? (issrc => $searchspec->{src} ? 1 : 0)
287                    : ()),
288                pkgid =>
289                    { IN => $c->forward('distrib_search', [ $searchspec
290                ])->get_column('pkgid')->as_query, }, 
291               
292         
293        },
294        {
295            %{$c->forward('search_param')},
296            select => [ 
297                "ts_rank_cd(to_tsvector('english', description),to_tsquery(?)) as rank",
298                'pkgid'
299            ],
300            bind => [ $tsquery ], 
301            order_by => [ 'rank desc', 'name', 'evr using >>', 'issrc' ],
302        },
303    );
304    $c->forward('format_search', $searchspec);
305}
306
307=head1 AUTHOR
308
309Olivier Thauvin
310
311=head1 LICENSE
312
313This library is free software. You can redistribute it and/or modify
314it under the same terms as Perl itself.
315
316=cut
317
318__PACKAGE__->meta->make_immutable;
319
3201;
Note: See TracBrowser for help on using the repository browser.