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

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