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

Last change on this file since 196 was 196, checked in by nanardon, 14 years ago
  • add title, keywords and co
  • spelling fix
File size: 11.8 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->redirect('/');
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
189
190=head2 rpms.maintainers( PKGID )
191
192Return the maintainers for this package.
193
194The list of maintainers is limited to distribution where the package is located.
195
196If the package is a binary the C<SOURCERPM> tag is used to find the source rpm
197name.
198
199=cut
200
201sub maintainers : XMLRPCLocal {
202    my ($self, $c, $pkgid) = @_;
203
204    my $binfo = $c->forward('/rpms/basicinfo', [ $pkgid ]);
205    my $rpmname;
206    if ($binfo->{issrc}) {
207        $rpmname = $binfo->{name};
208    } else {
209        my $sourcerpm = $c->forward('queryformat', [ $pkgid, '%{SOURCERPM}' ]);
210        $sourcerpm =~ /^(.*)-([^-]+)-([^-]+)\.[^\.]+.rpm$/;
211        $rpmname = $1;
212    }
213    my %dist;
214    foreach (@{ $c->forward('/rpms/location', [ $pkgid ]) }) {
215        $dist{$_->{distribution}} = 1;
216    }
217
218    $c->forward('/maintainers/byrpm', [ $rpmname, [ keys %dist ] ]);
219}
220
221sub rpms_ :PathPrefix :Chained :CaptureArgs(1) {
222    my ( $self, $c, $pkgid ) = @_;
223    $c->stash->{pkgid} = $pkgid if($pkgid);
224    {
225        my $match = $c->stash->{pkgid};
226    }
227    if (!$c->model('Base::Rpms')->find({ pkgid => $pkgid })) {
228        $c->go('/404/index');
229    }
230    my $info = $c->stash->{rpms}{info} =
231        $c->forward('info', [ $c->stash->{pkgid} ]);
232
233    $c->stash->{metatitle} = sprintf("%s-%s %s",
234        $info->{name},
235        $info->{evr},
236        $info->{issrc} ? 'src' : $info->{arch},
237    );
238    push(@{ $c->stash->{keywords} }, $info->{name}, $info->{evr},
239        $info->{issrc} ? 'src' : $info->{arch},);
240    $c->stash->{metarevisit} = 30;
241
242    $c->stash->{rpms}{location} =
243        $c->forward('location', [ $c->stash->{pkgid} ]);
244}
245
246sub rpms : Private {
247    my ( $self, $c, $pkgid, $subpart, @args) = @_;
248    # Because $c->forward don't take into account Chained sub
249    $c->forward('rpms_', [ $pkgid ]);
250    for ($subpart || '') {
251        /^deps$/      and $c->go('alldeps',   [ $pkgid, @args ]);
252        /^files$/     and $c->go('files',     [ $pkgid, @args ]);
253        /^changelog$/ and $c->go('changelog', [ $pkgid, @args ]);
254        /^location$/  and $c->go('location',  [ $pkgid, @args ]);
255    }
256    $c->stash->{rpmurl} = $c->req->path;
257
258    return $c->stash->{xmlrpc} = $c->stash->{rpms};
259}
260
261sub rpms__ : Chained('/rpms/rpms_') :PathPart('') :Args(0) :XMLRPCLocal {
262    my ( $self, $c ) = @_;
263
264    $c->go('rpms', [ $c->stash->{pkgid} ]);
265}
266
267
268sub alldeps :Chained('rpms_') :PathPart('deps') :Args(0) :XMLRPCLocal {
269    my ( $self, $c, $pkgid ) = @_;
270    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
271    $pkgid ||= $c->stash->{pkgid};
272
273    my %deps;
274    foreach (
275        $c->model('Base')->resultset('Deps')->search(
276            { 
277                pkgid => $pkgid,
278            },
279            { 
280                order_by => [ 'count' ],
281                select => [ 'rpmsenseflag("flags")',
282                    qw(depname flags evr deptype) ],
283                as => [ qw'sense depname flags evr deptype' ],
284
285            },
286        )->all) {
287        push( @{ $deps{$_->get_column('deptype')} },
288            {
289                name => $_->get_column('depname'),
290                flags => $_->get_column('flags'),
291                evr => $_->get_column('evr'),
292                sense => $_->get_column('sense'),
293            }
294        );
295    }
296    $c->stash->{xmlrpc} = \%deps;
297}
298
299sub files :Chained('rpms_') :PathPart('files') :Args(0) :XMLRPCLocal {
300    my ( $self, $c, $pkgid, $number ) = @_;
301    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
302    $pkgid ||= $c->stash->{pkgid};
303
304    if ($number) { # This come from a forward
305        $c->go('files_contents', [ $number ]);
306    }
307
308    my @col = qw(dirname basename md5 size count);
309    $c->stash->{xmlrpc} = [ map {
310        {
311            filename => $_->get_column('dirname') . $_->get_column('basename'),
312            dirname => $_->get_column('dirname'),
313            basename => $_->get_column('basename'),
314            md5 => $_->get_column('md5'),
315            perm => $_->get_column('perm'),
316            size => $_->get_column('size'),
317            user => $_->get_column('user'),
318            group => $_->get_column('group'),
319            has_content => $_->get_column('has_content'),
320            count => $_->get_column('count'),
321        }
322    } $c->model('Base')->resultset('Files')->search(
323            { 
324                pkgid => $pkgid,
325            },
326            { 
327                'select' => [ 'contents is NOT NULL as has_content', 'rpmfilesmode(mode) as perm', @col, '"group"',
328                    '"user"' ],
329                as => [ qw(has_content perm), @col, 'group', 'user' ],
330                order_by => [ 'dirname', 'basename' ],
331
332            },
333        )->all ];
334}
335
336sub files_contents :Chained('rpms_') :PathPart('files') :Args(1) {
337    my ( $self, $c, $number ) = @_;
338    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+/[^/]+:)[0];
339    my $pkgid = $c->stash->{pkgid};
340
341    $c->stash->{xmlrpc} = $c->model('Base::Files')->search(
342        {
343            pkgid => $pkgid,
344            count => $number,
345        },
346        {
347            select => ['contents'],
348        }
349    )->get_column('contents')->first;
350}
351
352sub changelog :Chained('rpms_') :PathPart('changelog') :Args(0) :XMLRPCLocal {
353    my ( $self, $c, $pkgid ) = @_;
354    $pkgid ||= $c->stash->{pkgid};
355    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
356
357    my @ch;
358    foreach ($c->model('Base')->resultset('RpmsChangelog')->search({},
359            { 
360                bind => [ $pkgid ],
361                order_by => [ 'time::int desc' ],
362            },
363        )->all) {
364        my $chentry;
365        my $enc = guess_encoding($_->get_column('text'), qw/latin1/);
366        $chentry->{text} = $enc && ref $enc
367            ? encode('utf8', $_->get_column('text'))
368            : $_->get_column('text');
369        $enc = guess_encoding($_->get_column('name'), qw/latin1/);
370        $chentry->{name} = $enc && ref $enc
371            ? encode('utf8', $_->get_column('name'))
372            : $_->get_column('name');
373        $chentry->{time} = $_->get_column('time');
374        $chentry->{date} = POSIX::strftime('%a %b %e %Y', gmtime($_->get_column('time')));
375        push(@ch, $chentry);
376    }
377
378    $c->stash->{xmlrpc} = \@ch;
379}
380
381=head2 rpms.location( PKGID )
382
383Return all distribution where the package having C<PKGID> can be found.
384
385=cut
386
387sub location :Chained('rpms_') :PathPart('location') :Args(0) {
388    my ( $self, $c, $pkgid ) = @_;
389    $pkgid ||= $c->stash->{pkgid};
390    $c->stash->{rpmurl} = ($c->req->path =~ m:(.*)/[^/]+:)[0];
391
392    $c->stash->{xmlrpc} = [
393        map {
394        {
395            distribution => $_->get_column('name'),
396            dist => $_->get_column('shortname'),
397            release => $_->get_column('version'),
398            arch => $_->get_column('arch'), 
399            media => $_->get_column('label'),
400            media_group => $_->get_column('group_label'),
401        }
402        }
403        $c->forward('/distrib/distrib_rs', [ {} ])
404         ->search_related('MediasPaths')
405                 ->search_related('Paths')
406        ->search_related('Rpmfiles',
407            { pkgid => $pkgid },
408            {
409                select => [ qw(shortname name version arch label group_label) ],
410                order_by => [ qw(name version arch label) ],
411            }
412        )->all ]
413}
414
415=head1 AUTHOR
416
417Olivier Thauvin
418
419=head1 LICENSE
420
421This library is free software. You can redistribute it and/or modify
422it under the same terms as Perl itself.
423
424=cut
425
426__PACKAGE__->meta->make_immutable;
427
4281;
Note: See TracBrowser for help on using the repository browser.