source: server/trunk/web/lib/Sophie/Controller/Distrib.pm @ 422

Last change on this file since 422 was 375, checked in by nanardon, 13 years ago
  • remove media not existing in dump when loading a distrib
File size: 17.9 KB
RevLine 
[2]1package Sophie::Controller::Distrib;
2use Moose;
3use namespace::autoclean;
4
5BEGIN {extends 'Catalyst::Controller'; }
6
7=head1 NAME
8
9Sophie::Controller::Distrib - Catalyst Controller
10
11=head1 DESCRIPTION
12
13Catalyst Controller.
14
15=head1 METHODS
16
17=cut
18
[184]19=head2 distrib.list( [ DISTRIBUTION [, RELEASE [, ARCH ]]]
20
[196]21List content of distrib according arguments given. IE list available
[184]22C<distribution> if no argument is given, list C<release> if C<DISTRIBUTION> is
23given, list C<arch> if both C<DISTRIBUTION> and C<RELEASE> are given. Etc... Up
24to give C<MEDIA> if C<ARCH> is specified.
25
26Results are given as C<ARRAY>.
27
28=cut
29
[4]30sub list :XMLRPC {
[5]31    my ( $self, $c, $distrib, $release, $arch ) = @_;
32
33    my $distribution;
34    if (ref $distrib) {
35        ($distribution, $release, $arch) = (
36            $distrib->{distribution},
37            $distrib->{release},
38            $distrib->{arch},
39        );
40    } else {
41        $distribution = $distrib;
42    }
43
[3]44    my $rs = $c->model('Base')->resultset('Distribution');
45    if (!$distribution) {
[21]46        return $c->stash->{xmlrpc} = [ map { $_->name }
47            $rs->search(undef, { order_by => ['name'] })->all ];
[3]48    }
[118]49    $rs = $rs->search({
50            -or => [
51                { name      => $distribution },
52                { shortname => $distribution },
53            ],
54        })->search_related('Release');
[3]55    if (!$release) {
[21]56        return $c->stash->{xmlrpc} = [ map { $_->version }
57            $rs->search(undef, { order_by => ['version'] })->all ];
[3]58    }
[375]59    $rs = $rs->search({ version => $release })->search_related('Arch');
[5]60    if (!$arch) {
[21]61        return $c->stash->{xmlrpc} = [ map { $_->arch } 
62            $rs->search(undef, { order_by => ['arch'] })->all ];
[5]63    }
[375]64    $rs = $rs->search({ arch => $arch })->search_related('Medias');
[21]65    return $c->stash->{xmlrpc} = [ map { $_->label }
66        $rs->search(undef, { order_by => ['label'] })->all ];
[4]67}
68
69sub struct :XMLRPC {
[55]70    my ( $self, $c, $distribution, $release, $arch ) = @_;
[5]71
[55]72    if (!ref $distribution) {
73        $distribution = {
74            distribution => $distribution,
75            release => $release,
76            arch => $arch,
77        }
[5]78    }
79
[55]80    my $rs = $c->forward('distrib_rs', [ $distribution ])
81        ->search({}, { order_by => 'label' });
[41]82    $c->stash->{xmlrpc} = [ map { 
[3]83        { 
84            label => $_->label,
85            group_label => $_->group_label,
86        } 
[41]87    } $rs->all ];
[3]88}
[2]89
[53]90sub distrib_rs : Private {
[92]91    my ( $self, $c, $distrib, $asfilter ) = @_;
92    if ($asfilter && !(
93            $distrib->{distribution} ||
94            $distrib->{release} ||
95            $distrib->{arch} ||
96            $distrib->{media} ||
97            $distrib->{media_group})) {
98        return;
99    }
100
[53]101    return $c->model('Base')->resultset('Distribution')
102        ->search(
103            {
104                $distrib->{distribution}
[118]105                    ? (-or => [
[349]106                            { 'me.name' =>      $distrib->{distribution} },
[118]107                            { shortname => $distrib->{distribution} },
108                        ],
109                    )
[53]110                    : ()
[55]111            },
[57]112            {
[114]113                select => [ qw(name shortname) ],
[57]114            }
[53]115        )->search_related('Release',
116            {
117                $distrib->{release}
118                    ? (version => $distrib->{release})
119                    : ()
[57]120            },
121            {
122                select => [ qw(version) ],
[53]123            }
124        )->search_related('Arch',
125            {
126                $distrib->{arch}
[349]127                    ? ('Arch.arch' => $distrib->{arch})
[53]128                    : ()
[57]129            },
130            {
131                select => [ qw(arch) ],
[53]132            }
133        )->search_related('Medias',
134            {
135                ($distrib->{media} ? (label => $distrib->{media}) : ()),
136                ($distrib->{media_group}
137                    ? (group_label => $distrib->{media_group})
138                    : ()),
[55]139            },
[57]140            {
141                select => [ qw(label group_label) ],
142            }
[53]143        );
144}
[3]145
[184]146=head2 distrib.exists( DISTRIB )
[55]147
[364]148Return true or false if distribution C<DISTRIB> exists.
[184]149
150C<DISTRIB> is a structure with following key/value:
151
152=over 4
153
154=item distribution
155
156The distribution name
157
158=item release
159
160The release name
161
162=item arch
163
164The arch name
165
166=back
167
[364]168This function is useful to check if a search have chance to succeed, eg if the
169user is not searching a rpm on a non existing distribution.
[184]170
171=cut
172
[53]173sub exists : XMLRPC {
174    my ( $self, $c, $d ) = @_;
175
176    my $rs = $c->forward('distrib_rs', [ $d ]);
177
178    if ($rs->search({}, { rows => 1 })->next) {
179        $c->stash->{xmlrpc} = 1;
180    } else {
181        $c->stash->{xmlrpc} = 0;
182    }
183}
184
[2]185=head2 index
186
187=cut
188
[184]189=head2 Url: /distrib
190
[364]191Return the list of currently indexed distributions.
[184]192
193=cut
194
[3]195sub index :Path :Chained :Args(0)  {
[2]196    my ( $self, $c ) = @_;
197
[196]198    $c->stash->{metarevisite} = 60;
199    $c->stash->{metatitle} = 'Available Distribution';
200    push(@{$c->stash->{keywords}}, 'Rpm Distribution');
[4]201    $c->forward('list');
[2]202}
203
[184]204=head2 release
[2]205
[3]206=cut
[2]207
[184]208=head2 Url: /distrib/<DISTRIBUTION>
209
[364]210Return the list of available releases for given C<DISTRIBUTION>.
[184]211
212=cut
213
[3]214sub list_release :Path :Args(1) {
[2]215    my ( $self, $c, $distribution ) = @_;
[17]216    $c->stash->{dist}{distribution} = $distribution;
[53]217    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
218        $c->go('/404/index');
219    }
[196]220    $c->stash->{metarevisite} = 60;
221    $c->stash->{metatitle} = 'Available release for ' . $distribution;
222    push(@{$c->stash->{keywords}}, $distribution);
[17]223    $c->forward('list', [ $c->stash->{dist} ] );
[2]224}
225
[184]226=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>
227
[364]228Return the list of available architectures for given C<DISTRIBUTION>,
[184]229C<RELEASE>.
230
231=cut
232
[3]233sub list_arch :Path :Args(2) {
234    my ( $self, $c, $distribution, $release ) = @_;
[226]235
236    # Compatability with Sophie1
237    if ($distribution =~ /^([^,]+,)?[^,]+,[^,]+$/) {
238        $c->go('/compat/distrib', [ $distribution, $release ]);
239    }
240
[17]241    $c->stash->{dist}{distribution} = $distribution;
242    $c->stash->{dist}{release} = $release;
[196]243    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
244        $c->go('/404/index');
245    }
246    $c->stash->{metarevisite} = 60;
247    $c->stash->{metatitle} =
248        'Available architecture for ' . $distribution . ' / ' . $release;
249    push(@{$c->stash->{keywords}}, $distribution, $release);
[17]250    $c->forward('list', [ $c->stash->{dist} ] );
[2]251}
252
[3]253
254sub distrib_view :PathPrefix :Chained :CaptureArgs(3) {
255    my ( $self, $c, $distribution, $release, $arch ) = @_;
[17]256    $c->stash->{dist}{distribution} = $distribution;
257    $c->stash->{dist}{release} = $release;
258    $c->stash->{dist}{arch} = $arch;
[196]259    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
260        $c->go('/404/index');
261    }
262    $c->stash->{metarevisite} = 60;
263    $c->stash->{metatitle} =
[275]264        $distribution . ' / ' . $release . ' / ' . $arch . ' content';
[196]265    push(@{$c->stash->{keywords}}, $distribution, $release, $arch);
[17]266    $c->stash->{distrib} = $c->stash->{dist};
[3]267}
268
[184]269=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>
270
[259]271Return the list of available medias for given C<DISTRIBUTION>,
[184]272C<RELEASE>, C<ARCH>.
273
274=cut
275
[54]276sub distrib :Chained('distrib_view') PathPart('') :Args(0) {
[3]277    my ( $self, $c ) = @_;
[21]278    $c->forward('list', [ $c->stash->{dist} ]);
[3]279}
280
[272]281# Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/media
282
[54]283sub media :Chained('/distrib/distrib_view') PathPart('media') :Args(0) {
[3]284    my ( $self, $c ) = @_;
[17]285    $c->forward('struct', [ $c->stash->{dist} ]);
[3]286}
287
[184]288=head2 distrib.anyrpms( DISTRIB )
289
[196]290Return a list of packages available for C<DISTRIB>.
[184]291
292C<DISTRIB> is a struct with following keys/values:
293
294=over 4
295
296=item distribution
297
298The distribution name
299
300=item release
301
302The release name
303
304=item arch
305
[364]306The archictecture name
[184]307
308=back
309
310=cut
311
[53]312sub anyrpms :XMLRPC {
[3]313    my ( $self, $c, $distribution, $release, $arch ) = @_;
[17]314
[53]315    if (!ref $distribution) {
316        $distribution = {
317            distribution => $distribution,
318            release => $release,
319            arch => $arch,
320        }
[17]321    }
[53]322
[273]323    $c->stash->{rpm} = [ map {
324        {
325        pkgid => $_->pkgid,
326        filename => $_->filename,
[3]327        }
[273]328        } $c->forward('/search/rpms/rpms_rs', [ $distribution ])
329        ->search(
330            {
331                $c->req->param('fl')
332                    ? ( filename => { ILIKE => $c->req->param('fl') . '%' } )
333                    : (),
334            }, { order_by => [ qw(filename) ] })
335        ->all ];
[53]336
337    $c->stash->{xmlrpc} = $c->stash->{rpm};
338}
339
[184]340=head2 distrib.rpms( DISTRIB )
341
[196]342Return a list of binary packages available for C<DISTRIB>.
[184]343
344C<DISTRIB> is a struct with following keys/values:
345
346=over 4
347
348=item distribution
349
350The distribution name
351
352=item release
353
354The release name
355
356=item arch
357
[364]358The architecture name
[184]359
360=back
361
362=cut
363
[53]364sub rpms :XMLRPC {
365    my ( $self, $c, $distribution, $release, $arch ) = @_;
366
367    if (!ref $distribution) {
368        $distribution = {
369            distribution => $distribution,
370            release => $release,
371            arch => $arch,
372        }
373    }
374
[273]375    $distribution->{src} = 0;
376
[53]377    $c->stash->{rpm} = [ map {
[273]378        {
379        pkgid => $_->pkgid,
380        filename => $_->filename,
[53]381        }
[273]382        } $c->forward('/search/rpms/rpms_rs', [ $distribution ])
383        ->search(
384            {
385                $c->req->param('fl')
386                    ? ( filename => { ILIKE => $c->req->param('fl') . '%' } )
387                    : (),
388            }, { order_by => [ qw(filename) ] })
389        ->all ];
[3]390
391    $c->stash->{xmlrpc} = $c->stash->{rpm};
392}
393
[184]394=head2 distrib.srpms( DISTRIB )
395
[364]396Return a list of source packages available for C<DISTRIB>.
[184]397
398C<DISTRIB> is a struct with following keys/values:
399
400=over 4
401
402=item distribution
403
404The distribution name
405
406=item release
407
408The release name
409
410=item arch
411
[364]412The architecture name
[184]413
414=back
415
416=cut
417
[3]418sub srpms :XMLRPC {
419    my ( $self, $c, $distribution, $release, $arch ) = @_;
[17]420
[53]421    if (!ref $distribution) {
422        $distribution = {
423            distribution => $distribution,
424            release => $release,
425            arch => $arch,
426        }
[17]427    }
428
[273]429    $distribution->{src} = 1;
430
431    $c->stash->{rpm} = [ map {
432        {
433        pkgid => $_->pkgid,
434        filename => $_->filename,
[3]435        }
[273]436        } $c->forward('/search/rpms/rpms_rs', [ $distribution ])
437        ->search(
438            {
439                $c->req->param('fl')
440                    ? ( filename => { ILIKE => $c->req->param('fl') . '%' } )
441                    : (),
442            }, { order_by => [ qw(filename) ] })
443        ->all ];
[3]444
445    $c->stash->{xmlrpc} = $c->stash->{rpm};
446}
447
[368]448=head2 distrib.rpms_name( DISTRIB )
449
450Return the list of rpm name available for C<DISTRIB>.
451
452C<DISTRIB> is a struct with following keys/values:
453
454=over 4
455
456=item distribution
457
458The distribution name
459
460=item release
461
462The release name
463
464=item arch
465
466The architecture name
467
468=back
469
470=cut
471
[53]472sub rpms_name :XMLRPC {
473    my ( $self, $c, $distribution, $release, $arch ) = @_;
474
475    if (!ref $distribution) {
476        $distribution = {
477            distribution => $distribution,
478            release => $release,
479            arch => $arch,
480        }
481    }
482
483    $c->stash->{xmlrpc} = [
484        $c->model('Base')->resultset('Rpms')->search(
485            { pkgid => {
486                IN =>
487        $c->forward('distrib_rs', [ $distribution ])
488        ->search_related('MediasPaths')
489        ->search_related('Paths')
490        ->search_related('Rpmfiles')->get_column('pkgid')->as_query
491        } },
492        { group_by => [ qw(name) ], order_by => [ qw(name) ] }
493        )->get_column('name')->all ];
494}
495
[184]496
[190]497=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms
[184]498
[259]499Return the list of available rpms for given C<DISTRIBUTION>,
[184]500C<RELEASE>, C<ARCH>.
501
502=cut
503
[76]504sub list_rpms :Chained('distrib_view') PathPart('rpms') Args(0) {
[3]505    my ( $self, $c ) = @_;
[272]506    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
507        $c->go('/404/index');
508    }
509    $c->stash->{metarevisite} = 60;
510    $c->stash->{metatitle} = sprintf(
511        'Available Rpms for %s / %s / %s',
512        $c->stash->{dist}{distribution},
513        $c->stash->{dist}{release},
514        $c->stash->{dist}{arch}
515    );
516    push(@{$c->stash->{keywords}},
517        $c->stash->{dist}{distribution},
518        $c->stash->{dist}{release},
519        $c->stash->{dist}{arch});
[184]520    $c->forward('rpms', [ $c->stash->{dist} ]);
[3]521}
522
[190]523=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms
524
[364]525Return the list of available source rpms for given C<DISTRIBUTION>,
[190]526C<RELEASE>, C<ARCH>.
527
528=cut
529
[76]530sub list_srpms :Chained('distrib_view') PathPart('srpms') Args(0) {
[3]531    my ( $self, $c ) = @_;
[272]532    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
533        $c->go('/404/index');
534    }
535    $c->stash->{metarevisite} = 60;
536    $c->stash->{metatitle} = sprintf(
537        'Available Srpms for %s / %s / %s',
538        $c->stash->{dist}{distribution},
539        $c->stash->{dist}{release},
540        $c->stash->{dist}{arch}
541    );
542    push(@{$c->stash->{keywords}},
543        $c->stash->{dist}{distribution},
544        $c->stash->{dist}{release},
545        $c->stash->{dist}{arch});
[184]546    $c->forward('srpms', [ $c->stash->{dist} ]);
[3]547}
548
[190]549=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms/<RPMNAME>
550
[364]551Show the highest version of source rpm named C<RPMNAME> for given
[190]552C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
553
554=cut
555
[76]556sub srpm_by_name :Chained('distrib_view') PathPart('srpms') {
557    my ($self, $c, $name, @subpart) = @_;
[50]558    $c->stash->{dist}{src} = 1;
[148]559    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
560        [ $c->stash->{dist}, $name ]) };
[50]561    $c->go('/404/index') unless ($c->stash->{pkgid});
[272]562    push(@{$c->stash->{keywords}},
563        $c->stash->{dist}{distribution},
564        $c->stash->{dist}{release},
565        $c->stash->{dist}{arch});
[76]566    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]567}
[50]568
[190]569=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms/<RPMNAME>
570
[364]571Show the highest version of binary rpm named C<RPMNAME> for given
[190]572C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
573
574=cut
575
[76]576sub rpm_by_name :Chained('distrib_view') PathPart('rpms') {
577    my ($self, $c, $name, @subpart) = @_;
[50]578    $c->stash->{dist}{src} = 0;
[148]579    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
580        [ $c->stash->{dist}, $name ]) };
[50]581    $c->go('/404/index') unless ($c->stash->{pkgid});
[272]582    push(@{$c->stash->{keywords}},
583        $c->stash->{dist}{distribution},
584        $c->stash->{dist}{release},
585        $c->stash->{dist}{arch});
[76]586    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]587}
[50]588
[190]589
590=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/by-pkgid/<PKGID>
591
592Show information about rpm having pkgid C<PKGID> for given
593C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
594
[364]595This is likely the same thing than C</rpm/PKGID> but website will return a 404
596error code if the rpm is not in this distrib
[190]597
598=cut
599
[54]600sub rpm_bypkgid :Chained('distrib_view') PathPart('by-pkgid') {
[82]601    my ( $self, $c, $pkgid, @subpart ) = @_;
[54]602    if ($pkgid) {
[148]603        if (@{ $c->forward('/search/rpm/bypkgid',
604            [ $c->stash->{dist}, $pkgid ]) } ) {
[82]605            $c->go('/rpms/rpms', [ $pkgid, @subpart ]);
[272]606            push(@{$c->stash->{keywords}},
607                $c->stash->{dist}{distribution},
608                $c->stash->{dist}{release},
609                $c->stash->{dist}{arch});
[55]610        } else {
611            $c->go('/404/index');
612        }
[54]613    } else {
614        $c->forward('anyrpms', [ $c->stash->{dist} ]);
615    }
[3]616}
617
618sub _media_list_rpms :Chained('distrib_view') PathPart('media') CaptureArgs(1) {
619    my ( $self, $c, $media ) = @_;
[53]620    $c->stash->{dist}{media} = $media;
[272]621    push(@{$c->stash->{keywords}},
622        $c->stash->{dist}{distribution},
623        $c->stash->{dist}{release},
624        $c->stash->{dist}{arch},
625        $c->stash->{dist}{media},
626    );
[3]627}
628
[262]629=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>
630
631Return the list of rpms in media C<MEDIA> for distribution C<DISTRIB>,
632C<RELEASE>, C<ARCH>.
633
[364]634The result list is an array of struct:
[262]635
636    [
637        {
638            filename => 'zvbi-0.2.33-5.fc14.x86_64.rpm',
639            pkgid => 'bb9cc5113f0de3e4c7140a1ee8694900'
640        },
641        {
642            filename => 'zvbi-devel-0.2.33-5.fc14.i686.rpm',
643            pkgid => '2c3b41c5e1c475dfa31492998eb4de9f'
644        }
645    ]
646
647=cut
648
[54]649sub media_list_rpms :Chained('_media_list_rpms') PathPart('') :Args(0) {
[3]650    my ( $self, $c ) = @_;
[53]651    $c->forward('anyrpms', [ $c->stash->{dist} ]);
[3]652}
[21]653
[262]654=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/rpms/<NAME>
655
656Show binary rpm named C<NAME> in this distribution/media.
657
658Return C<404> error if such rpm does not exists
659
660=cut
661
[54]662sub media_rpm_byname :Chained('_media_list_rpms') PathPart('rpms') {
[262]663    my ( $self, $c, $name, @subpart ) = @_;
664    $c->stash->{dist}{src} = 0;
665    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
666        [ $c->stash->{dist}, $name ]) };
667    $c->go('/404/index') unless ($c->stash->{pkgid});
668    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]669}
[262]670
671=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/srpms/<NAME>
672
673Show source rpm named C<NAME> in this distribution/media.
674
675Return C<404> error if such rpm does not exists
676
677=cut
678
[54]679sub media_srpm_byname :Chained('_media_list_rpms') PathPart('srpms') {
[262]680    my ( $self, $c, $name, @subpart ) = @_;
[263]681    $c->stash->{dist}{src} = 1;
[262]682    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
683        [ $c->stash->{dist}, $name ]) };
684    $c->go('/404/index') unless ($c->stash->{pkgid});
685    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]686}
[54]687
[262]688=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/by-pkgid/<PKGID>
689
690Show rpm having C<PKGID> in this distribution/media.
691
692Return C<404> error if such rpm does not exists
693
694=cut
695
[21]696sub media_rpm_bypkgid :Chained('_media_list_rpms') PathPart('by-pkgid') {
[76]697    my ( $self, $c, $pkgid, @part ) = @_;
[54]698    if ($pkgid) {
[148]699        if (@{ $c->forward('/search/rpm/bypkgid', [ $c->stash->{dist}, $pkgid
700            ]) } ) {
[57]701            $c->stash->{pkgid} = $pkgid;
[76]702            $c->go('/rpms/rpms', [ $pkgid, @part ]);
[55]703        } else {
704            $c->go('/404/index');
705        }
[54]706    } else {
707        $c->forward('anyrpms', [ $c->stash->{dist} ]);
708    }
[3]709}
710
[2]711=head1 AUTHOR
712
713Olivier Thauvin
714
715=head1 LICENSE
716
717This library is free software. You can redistribute it and/or modify
718it under the same terms as Perl itself.
719
720=cut
721
722__PACKAGE__->meta->make_immutable;
723
7241;
Note: See TracBrowser for help on using the repository browser.