source: server/trunk/web/lib/Sophie/Controller/Rpms.pm @ 150

Last change on this file since 150 was 123, checked in by nanardon, 14 years ago
  • fix binaries/sources search on nosrc.rpm
File size: 10.7 KB
Line 
1package Sophie::Controller::Rpms;
2use Moose;
3use namespace::autoclean;
4use Encode::Guess;
5use Encode;
6use POSIX;
7
8BEGIN {extends 'Catalyst::Controller'; }
9
10=head1 NAME
11
12Sophie::Controller::Rpms - Catalyst Controller
13
14=head1 DESCRIPTION
15
16Catalyst Controller.
17
18=head1 METHODS
19
20=cut
21
22
23=head2 index
24
25=cut
26
27sub index :Path :Args(0) {
28    my ( $self, $c ) = @_;
29
30    $c->response->body('Matched Sophie::Controller::Rpms in Rpms.');
31}
32
33=head2 rpms.queryformat PKGID, FORMAT
34
35Perform an C<rpm -q --qf> on the package having C<PKGID>.
36
37=cut
38
39sub queryformat : XMLRPCLocal {
40    my ( $self, $c, $pkgid, $qf ) = @_;
41    $c->stash->{xmlrpc} = $c->model('base')->resultset('Rpms')->search(
42        { pkgid => $pkgid },
43        { 
44            select => [ qq{rpmqueryformat("header", ?)} ],
45            as => [ 'qf' ],
46            bind => [ $qf ],
47        }
48    )->next->get_column('qf');
49}
50
51=head2 rpms.tag PKGID, TAG
52
53Return the list of C<TAG> values for package C<PKGID>
54
55=cut
56
57sub tag : XMLRPCLocal {
58    my ( $self, $c, $pkgid, $tag ) = @_;
59    $c->stash->{xmlrpc} = [ map { $_->get_column('tag') } $c->model('Base')->resultset('Rpms')->search(
60        { pkgid => $pkgid },
61        { 
62            select => [ qq{rpmquery("header", rpmtag(?))} ],
63            as => [ 'tag' ],
64            bind => [ $tag ], 
65        }
66    )->all ]
67}
68
69sub basicinfo : XMLRPCLocal {
70    my ($self, $c, $pkgid) = @_;
71
72    my $rpm = $c->model('base::Rpms')->find(
73        { pkgid => $pkgid },
74    );
75    $rpm or return;
76    my %info = $rpm->get_columns;
77    $info{src} = $info{issrc} ? 1 : 0;
78    foreach (qw(version release arch)) {
79        if (my $r = $c->model('base')->resultset('Rpms')->search(
80            { pkgid => $pkgid },
81            { 
82                select => [ qq{rpmquery("header", ?)} ],
83                as => [ 'qf' ],
84                bind => [ $_ ],
85            }
86            )->next) { 
87            $info{$_} = $r->get_column('qf');
88        }
89    }
90
91    return $c->stash->{xmlrpc} = \%info;
92}
93
94
95sub info : XMLRPCLocal {
96    my ($self, $c, $pkgid) = @_;
97
98
99    my $info = $c->forward('basicinfo', [ $pkgid ]);
100    foreach (qw(name epoch url group size packager
101                url sourcerpm license buildhost
102                distribution)) {
103        if (my $r = $c->model('base')->resultset('Rpms')->search(
104            { pkgid => $pkgid },
105            { 
106                select => [ qq{rpmquery("header", ?)} ],
107                as => [ 'qf' ],
108                bind => [ $_ ],
109            }
110            )->next) { 
111            $info->{$_} = $r->get_column('qf');
112        }
113    }
114
115    return $c->stash->{xmlrpc} = $info;
116}
117
118sub deps : XMLRPCLocal {
119    my ($self, $c, $pkgid, $deptype) = @_;
120
121    @{ $c->stash->{xmlrpc}{deps}{$deptype} } = 
122        map { 
123            { 
124                name => $_->get_column('depname'),
125                flags => $_->get_column('flags'),
126                evr => $_->get_column('evr'),
127                sense => $_->get_column('sense'),
128            }
129        } 
130        $c->model('Base')->resultset('Deps')->search(
131            { 
132                pkgid => $pkgid,
133                deptype => $deptype,
134            },
135            { 
136                order_by => [ 'count' ],
137                select => [ 'rpmsenseflag("flags")', qw(depname flags evr) ],
138                as => [ qw'sense depname flags evr' ],
139
140            },
141        )->all;
142}
143
144sub sources : XMLRPCLocal {
145    my ( $self, $c, $pkgid ) = @_;
146
147    my $sourcerpm = $c->forward('queryformat', [ $pkgid, '%{SOURCERPM}' ]);
148    my $nosourcerpm = $sourcerpm;
149    $nosourcerpm =~ s/\.src.rpm$/\.nosrc.rpm/;
150
151    $c->stash->{xmlrpc} = [ $c->model('Base::Rpms')->search(
152        {
153            pkgid => { 
154                IN => $c->model('Base::RpmFile')->search(
155                    { filename => [ $sourcerpm, $nosourcerpm ] }
156                )->get_column('pkgid')->as_query
157            },
158        }
159    )->get_column('pkgid')->all ];
160}
161
162sub binaries : XMLRPCLocal {
163    my ( $self, $c, $pkgid ) = @_;
164
165    my $sourcerpm = $c->forward('queryformat', [ $pkgid,
166            '%{NAME}-%{VERSION}-%{RELEASE}.src.rpm' ]);
167    my $nosourcerpm = $sourcerpm;
168    $nosourcerpm =~ s/\.src.rpm$/\.nosrc.rpm/;
169
170    my $tagrs = $c->model('Base')->resultset('Tags')
171        ->search({ tagname => 'sourcerpm', value => [ $sourcerpm, $nosourcerpm ] })
172        ->get_column('pkgid');
173    $c->stash->{xmlrpc} = [ $c->model('Base::Rpms')->search(
174        {
175            -and => [
176                { issrc => 0 },
177                { pkgid =>
178                    { IN => $tagrs->as_query, },
179                },
180            ]
181        },
182        {
183            order_by => [ qw(arch name), 'evr using >>' ],
184        },
185    )->get_column('pkgid')->all ];
186
187}
188
189sub rpms_ :PathPrefix :Chained :CaptureArgs(1) {
190    my ( $self, $c, $pkgid ) = @_;
191    $c->stash->{pkgid} = $pkgid if($pkgid);
192    {
193        my $match = $c->stash->{pkgid};
194    }
195    #$c->model('Base')->resultset('Rpms')->search(pkgid => $pkgid)->next;
196    $c->stash->{rpms}{info} =
197        $c->forward('info', [ $c->stash->{pkgid} ]);
198    $c->stash->{rpms}{location} =
199        $c->forward('location', [ $c->stash->{pkgid} ]);
200}
201
202sub rpms : Private {
203    my ( $self, $c, $pkgid, $subpart, @args) = @_;
204    # Because $c->forward don't take into account Chained sub
205    $c->forward('rpms_', [ $pkgid ]);
206    for ($subpart || '') {
207        /^deps$/      and $c->go('alldeps',   [ $pkgid, @args ]);
208        /^files$/     and $c->go('files',     [ $pkgid, @args ]);
209        /^changelog$/ and $c->go('changelog', [ $pkgid, @args ]);
210        /^location$/  and $c->go('location',  [ $pkgid, @args ]);
211    }
212    $c->stash->{rpmurl} = $c->req->path;
213
214    return $c->stash->{xmlrpc} = $c->stash->{rpms};
215}
216
217sub rpms__ : Chained('/rpms/rpms_') :PathPart('') :Args(0) :XMLRPCLocal {
218    my ( $self, $c ) = @_;
219
220    $c->go('rpms', [ $c->stash->{pkgid} ]);
221}
222
223
224sub alldeps :Chained('rpms_') :PathPart('deps') :Args(0) :XMLRPCLocal {
225    my ( $self, $c, $pkgid ) = @_;
226    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
227    $pkgid ||= $c->stash->{pkgid};
228
229    my %deps;
230    foreach (
231        $c->model('Base')->resultset('Deps')->search(
232            { 
233                pkgid => $pkgid,
234            },
235            { 
236                order_by => [ 'count' ],
237                select => [ 'rpmsenseflag("flags")',
238                    qw(depname flags evr deptype) ],
239                as => [ qw'sense depname flags evr deptype' ],
240
241            },
242        )->all) {
243        push( @{ $deps{$_->get_column('deptype')} },
244            {
245                name => $_->get_column('depname'),
246                flags => $_->get_column('flags'),
247                evr => $_->get_column('evr'),
248                sense => $_->get_column('sense'),
249            }
250        );
251    }
252    $c->stash->{xmlrpc} = \%deps;
253}
254
255sub files :Chained('rpms_') :PathPart('files') :Args(0) :XMLRPCLocal {
256    my ( $self, $c, $pkgid, $number ) = @_;
257    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
258    $pkgid ||= $c->stash->{pkgid};
259
260    if ($number) { # This come from a forward
261        $c->go('files_contents', [ $number ]);
262    }
263
264    my @col = qw(dirname basename md5 size count);
265    $c->stash->{xmlrpc} = [ map {
266        {
267            filename => $_->get_column('dirname') . $_->get_column('basename'),
268            dirname => $_->get_column('dirname'),
269            basename => $_->get_column('basename'),
270            md5 => $_->get_column('md5'),
271            perm => $_->get_column('perm'),
272            size => $_->get_column('size'),
273            user => $_->get_column('user'),
274            group => $_->get_column('group'),
275            has_content => $_->get_column('has_content'),
276            count => $_->get_column('count'),
277        }
278    } $c->model('Base')->resultset('Files')->search(
279            { 
280                pkgid => $pkgid,
281            },
282            { 
283                'select' => [ 'contents is NOT NULL as has_content', 'rpmfilesmode(mode) as perm', @col, '"group"',
284                    '"user"' ],
285                as => [ qw(has_content perm), @col, 'group', 'user' ],
286                order_by => [ 'dirname', 'basename' ],
287
288            },
289        )->all ];
290}
291
292sub files_contents :Chained('rpms_') :PathPart('files') :Args(1) {
293    my ( $self, $c, $number ) = @_;
294    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+/[^/]+:)[0];
295    my $pkgid = $c->stash->{pkgid};
296
297    $c->stash->{xmlrpc} = $c->model('Base::Files')->search(
298        {
299            pkgid => $pkgid,
300            count => $number,
301        },
302        {
303            select => ['contents'],
304        }
305    )->get_column('contents')->first;
306}
307
308sub changelog :Chained('rpms_') :PathPart('changelog') :Args(0) :XMLRPCLocal {
309    my ( $self, $c, $pkgid ) = @_;
310    $pkgid ||= $c->stash->{pkgid};
311    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
312
313    my @ch;
314    foreach ($c->model('Base')->resultset('RpmsChangelog')->search({},
315            { 
316                bind => [ $pkgid ],
317                order_by => [ 'time::int desc' ],
318            },
319        )->all) {
320        my $chentry;
321        my $enc = guess_encoding($_->get_column('text'), qw/latin1/);
322        $chentry->{text} = $enc && ref $enc
323            ? encode('utf8', $_->get_column('text'))
324            : $_->get_column('text');
325        $enc = guess_encoding($_->get_column('name'), qw/latin1/);
326        $chentry->{name} = $enc && ref $enc
327            ? encode('utf8', $_->get_column('name'))
328            : $_->get_column('name');
329        $chentry->{time} = $_->get_column('time');
330        $chentry->{date} = POSIX::strftime('%a %b %e %Y', gmtime($_->get_column('time')));
331        push(@ch, $chentry);
332    }
333
334    $c->stash->{xmlrpc} = \@ch;
335}
336
337=head2 rpms.location (PKGID)
338
339Return all distribution where the package having C<PKGID> can be found.
340
341=cut
342
343sub location :Chained('rpms_') :PathPart('location') :Args(0) {
344    my ( $self, $c, $pkgid ) = @_;
345    $pkgid ||= $c->stash->{pkgid};
346    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
347
348    $c->stash->{xmlrpc} = [
349        map {
350        {
351            distribution => $_->get_column('name'),
352            dist => $_->get_column('shortname'),
353            release => $_->get_column('version'),
354            arch => $_->get_column('arch'), 
355            media => $_->get_column('label'),
356            media_group => $_->get_column('group_label'),
357        }
358        }
359        $c->forward('/distrib/distrib_rs', [ {} ])
360         ->search_related('MediasPaths')
361                 ->search_related('Paths')
362        ->search_related('Rpmfiles',
363            { pkgid => $pkgid },
364            {
365                select => [ qw(shortname name version arch label group_label) ],
366                order_by => [ qw(name version arch label) ],
367            }
368        )->all ]
369}
370
371=head1 AUTHOR
372
373Olivier Thauvin
374
375=head1 LICENSE
376
377This library is free software. You can redistribute it and/or modify
378it under the same terms as Perl itself.
379
380=cut
381
382__PACKAGE__->meta->make_immutable;
383
3841;
Note: See TracBrowser for help on using the repository browser.