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

Last change on this file since 53 was 53, checked in by nanardon, 14 years ago
  • factorize code
  • add some view in distrib/
File size: 8.2 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 bytag : XMLRPCPath('/search/rpm/bytag') {
75    my ( $self, $c, $searchspec, $tag, $tagvalue ) = @_;
76
77    my $tagrs = $c->model('Base')->resultset('Tags')
78        ->search({ tagname => lc($tag), value => $tagvalue})
79        ->get_column('pkgid');
80    $c->stash->{xmlrpc} = [ $c->model('Base')->resultset('Rpms')->search(
81        {
82            -and => [ 
83                (exists($searchspec->{src})
84                    ? { issrc => $searchspec->{src} ? 1 : 0 }
85                    : ()),
86                { pkgid => 
87                    { IN => $tagrs->as_query, },
88                },
89                { pkgid =>
90                    { IN => $c->forward('distrib_search', [ $searchspec
91                        ])->get_column('pkgid')->as_query, }, 
92                },
93            ]     
94        },
95        $c->forward('search_param'),
96    )->get_column('pkgid')->all ]
97
98}
99
100sub bydep : XMLRPCPath('/search/rpm/bydep') {
101    my ( $self, $c, $searchspec, $deptype, $depname, $depsense, $depevr ) = @_;
102
103    my $deprs = $c->model('Base')->resultset('Deps')->search(
104        {
105            deptype => $deptype,
106            depname => $depname,
107            ($depsense
108                ? (-nest => \[
109                    'rpmdepmatch(flags, evr, rpmsenseflag(?), ?)',
110                    [ plain_text => $depsense],
111                    [ plain_text => $depevr ]
112                ])
113            : ()),
114        }
115    )->get_column('pkgid');
116    $c->stash->{xmlrpc} = [ $c->model('Base')->resultset('Rpms')->search(
117        {
118            -and => [ 
119                (exists($searchspec->{src})
120                    ? { issrc => $searchspec->{src} ? 1 : 0 }
121                    : ()),
122                { pkgid => 
123                    { IN => $deprs->as_query, },
124                },
125                { pkgid =>
126                    { IN => $c->forward('distrib_search', [ $searchspec
127                        ])->get_column('pkgid')->as_query, }, 
128                },
129            ]     
130        },
131        $c->forward('search_param'),
132    )->get_column('pkgid')->all ]
133}
134
135sub byfile : XMLRPCPath('/search/rpm/byfile') {
136    my ( $self, $c, $searchspec, $file) = @_;
137    my ($dirname, $basename) = $file =~ m:^(.*/)?([^/]+)$:;
138
139    my $filers = $c->model('Base')->resultset('Files')
140    ->search({
141            ($dirname
142                ? (dirname => $dirname)
143                : ()),
144            basename => $basename,
145        })
146    ->get_column('pkgid');
147    $c->stash->{xmlrpc} = [ $c->model('Base')->resultset('Rpms')->search(
148        {
149            -and => [ 
150                (exists($searchspec->{src})
151                    ? { issrc => $searchspec->{src} ? 1 : 0 }
152                    : ()),
153                { pkgid => 
154                    { IN => $filers->as_query, },
155                },
156                { pkgid =>
157                    { IN => $c->forward('distrib_search', [ $searchspec
158                        ])->get_column('pkgid')->as_query, }, 
159                },
160            ]     
161        },
162        $c->forward('search_param'),
163    )->get_column('pkgid')->all ]
164}
165
166sub fuzzy : XMLRPCPath('/search/rpm/fuzzy') {
167    my ($self, $c, $searchspec, $name) = @_;
168
169    my $deprs = $c->model('Base')->resultset('Deps')->search(
170        { deptype => 'P', depname => { '~*' => $name } }
171    )->get_column('pkgid');
172
173    $c->stash->{rs} = 
174
175        $c->model('Base')->resultset('Rpms')->search(
176        {
177            -and => [
178                (exists($searchspec->{src})
179                    ? { issrc => $searchspec->{src} ? 1 : 0 }
180                    : ()),
181                { -or => [
182                    { name => 
183                        { '~*' => $name, },
184                    },
185                    { pkgid =>
186                        { IN => $deprs->as_query, },
187                    }, ]
188                },
189                { pkgid =>
190                    { IN => $c->forward('distrib_search', [ $searchspec
191                        ])->get_column('pkgid')->as_query, }, 
192                },
193            ]     
194        },
195        $c->forward('search_param'),
196    );
197   
198    if ($c->req->xmlrpc->method) {
199        $c->stash->{xmlrpc} = [ 
200            $c->stash->{rs}->get_column('pkgid')->all
201        ];
202    }
203}
204
205sub quick : XMLRPCPath('/search/rpm/quick') {
206    my ($self, $c, $searchspec, @keywords) = @_;
207    my $tsquery = join(' & ', map { $_ =~ s/ /\\ /g; $_ } @keywords);
208    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
209            {
210                -or => [
211                    { -nest => \[
212                        "to_tsvector('english', description) @@ to_tsquery(?)",
213                        [ plain_text => $tsquery],
214                    ], },
215                    {
216                    name => [ @keywords ],
217                    },
218                ],
219            (exists($searchspec->{src})
220                ? (issrc => $searchspec->{src} ? 1 : 0)
221                : ()),
222            pkgid =>
223            { IN => $c->forward('distrib_search', [ $searchspec
224                    ])->get_column('pkgid')->as_query, }, 
225
226
227        },
228        {
229            %{$c->forward('search_param')},
230        },
231    );
232    if ($c->req->xmlrpc->method) {
233        $c->stash->{xmlrpc} = [ 
234            $c->stash->{rs}->get_column('pkgid')->all
235        ];
236    }
237}
238
239sub description : XMLRPCPath('/search/rpm/description') {
240    my ($self, $c, $searchspec, @keywords) = @_;
241    my $tsquery = join(' & ', map { $_ =~ s/ /\\ /g; $_ } @keywords);
242    $c->stash->{rs} = $c->model('Base')->resultset('Rpms')->search(
243        {
244            -nest => \[
245                    "to_tsvector('english', description) @@ to_tsquery(?)",
246                    [ plain_text => $tsquery],
247                ],
248                (exists($searchspec->{src})
249                    ? (issrc => $searchspec->{src} ? 1 : 0)
250                    : ()),
251                pkgid =>
252                    { IN => $c->forward('distrib_search', [ $searchspec
253                ])->get_column('pkgid')->as_query, }, 
254               
255         
256        },
257        {
258            %{$c->forward('search_param')},
259            select => [ 
260                "ts_rank_cd(to_tsvector('english', description),to_tsquery(?)) as rank",
261                'pkgid'
262            ],
263            bind => [ $tsquery ], 
264            order_by => [ 'rank desc', 'name', 'evr using >>', 'issrc' ],
265        },
266    );
267    if ($c->req->xmlrpc->method) {
268        $c->stash->{xmlrpc} = [ 
269            $c->stash->{rs}->get_column('pkgid')->all
270        ];
271    }
272}
273
274=head1 AUTHOR
275
276Olivier Thauvin
277
278=head1 LICENSE
279
280This library is free software. You can redistribute it and/or modify
281it under the same terms as Perl itself.
282
283=cut
284
285__PACKAGE__->meta->make_immutable;
286
2871;
Note: See TracBrowser for help on using the repository browser.