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

Last change on this file since 262 was 262, checked in by nanardon, 14 years ago
  • complete /distrib doc and feature
File size: 16.1 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    }
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    }
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 => [
106                            { name =>      $distrib->{distribution} },
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}
127                    ? (arch => $distrib->{arch})
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
[184]148Return true or false if disteibution C<DISTRIB> exists.
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
168This function is usefull to check if a search have chance to suceed, eg if the
169user is not searching a rpm on a not existing ditribution.
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
191Return the list of currently stored distributions.
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
[259]210Return the list of available release 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
[259]228Return the list of available architecture 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} =
264        'Available medias for ' . $distribution . ' / ' . $release . ' / ' . $arch;
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    # TODO store properly results
280    # No call from json here
281}
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
306The arch name
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
[3]323    @{$c->stash->{rpm}} = map {
324            { 
325              pkgid => $_->pkgid,
326              filename => $_->filename,
327            }
328        }
[53]329        $c->forward('distrib_rs', [ $distribution ])
[3]330        ->search_related('MediasPaths')
331        ->search_related('Paths')
[254]332        ->search_related('Rpmfiles', {}, { order_by => qw(filename) })
[53]333        ->all;
334
335    $c->stash->{xmlrpc} = $c->stash->{rpm};
336}
337
[184]338=head2 distrib.rpms( DISTRIB )
339
[196]340Return a list of binary packages available for C<DISTRIB>.
[184]341
342C<DISTRIB> is a struct with following keys/values:
343
344=over 4
345
346=item distribution
347
348The distribution name
349
350=item release
351
352The release name
353
354=item arch
355
356The arch name
357
358=back
359
360=cut
361
[53]362sub rpms :XMLRPC {
363    my ( $self, $c, $distribution, $release, $arch ) = @_;
364
365    if (!ref $distribution) {
366        $distribution = {
367            distribution => $distribution,
368            release => $release,
369            arch => $arch,
370        }
371    }
372
373    $c->stash->{rpm} = [ map {
374            { 
375              pkgid => $_->pkgid,
376              filename => $_->filename,
377            }
378        }
379        $c->forward('distrib_rs', [ $distribution ])
380        ->search_related('MediasPaths')
381        ->search_related('Paths')
[3]382        ->search_related('Rpmfiles', {
383            pkgid => {
384                IN => $c->model('Base')->resultset('Rpms')
385                ->search({ issrc => 'false' })->get_column('pkgid') ->as_query }
[254]386        },
387        { order_by => [ qw(filename) ] }
388        )->all ];
[3]389
390    $c->stash->{xmlrpc} = $c->stash->{rpm};
391}
392
[184]393=head2 distrib.srpms( DISTRIB )
394
[196]395Return a list of sources packages available for C<DISTRIB>.
[184]396
397C<DISTRIB> is a struct with following keys/values:
398
399=over 4
400
401=item distribution
402
403The distribution name
404
405=item release
406
407The release name
408
409=item arch
410
411The arch name
412
413=back
414
415=cut
416
[3]417sub srpms :XMLRPC {
418    my ( $self, $c, $distribution, $release, $arch ) = @_;
[17]419
[53]420    if (!ref $distribution) {
421        $distribution = {
422            distribution => $distribution,
423            release => $release,
424            arch => $arch,
425        }
[17]426    }
427
[3]428    @{$c->stash->{rpm}} = map {
429            { 
430              pkgid => $_->pkgid,
431              filename => $_->filename,
432            }
433        }
[53]434        $c->forward('distrib_rs', [ $distribution ])
[3]435        ->search_related('MediasPaths')
436        ->search_related('Paths')
437        ->search_related('Rpmfiles', {
438            pkgid => {
439                IN => $c->model('Base')->resultset('Rpms')
440                ->search({ issrc => 'true' })->get_column('pkgid') ->as_query }
[254]441        },
442        { order_by => [ qw(filename) ] }
443        )->all;
[3]444
445    $c->stash->{xmlrpc} = $c->stash->{rpm};
446}
447
[53]448sub rpms_name :XMLRPC {
449    my ( $self, $c, $distribution, $release, $arch ) = @_;
450
451    if (!ref $distribution) {
452        $distribution = {
453            distribution => $distribution,
454            release => $release,
455            arch => $arch,
456        }
457    }
458
459    $c->stash->{xmlrpc} = [
460        $c->model('Base')->resultset('Rpms')->search(
461            { pkgid => {
462                IN =>
463        $c->forward('distrib_rs', [ $distribution ])
464        ->search_related('MediasPaths')
465        ->search_related('Paths')
466        ->search_related('Rpmfiles')->get_column('pkgid')->as_query
467        } },
468        { group_by => [ qw(name) ], order_by => [ qw(name) ] }
469        )->get_column('name')->all ];
470}
471
[184]472
[190]473=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms
[184]474
[259]475Return the list of available rpms for given C<DISTRIBUTION>,
[184]476C<RELEASE>, C<ARCH>.
477
478=cut
479
[76]480sub list_rpms :Chained('distrib_view') PathPart('rpms') Args(0) {
[3]481    my ( $self, $c ) = @_;
[184]482    $c->forward('rpms', [ $c->stash->{dist} ]);
[3]483}
484
[190]485=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms
486
[259]487Return the list of available sources rpms for given C<DISTRIBUTION>,
[190]488C<RELEASE>, C<ARCH>.
489
490=cut
491
[76]492sub list_srpms :Chained('distrib_view') PathPart('srpms') Args(0) {
[3]493    my ( $self, $c ) = @_;
[184]494    $c->forward('srpms', [ $c->stash->{dist} ]);
[3]495}
496
[190]497=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms/<RPMNAME>
498
499Show the highter version of source rpm named C<RPMNAME> for given
500C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
501
502=cut
503
[76]504sub srpm_by_name :Chained('distrib_view') PathPart('srpms') {
505    my ($self, $c, $name, @subpart) = @_;
[50]506    $c->stash->{dist}{src} = 1;
[148]507    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
508        [ $c->stash->{dist}, $name ]) };
[50]509    $c->go('/404/index') unless ($c->stash->{pkgid});
[76]510    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]511}
[50]512
[190]513=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms/<RPMNAME>
514
515Show the highter version of binary rpm named C<RPMNAME> for given
516C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
517
518=cut
519
[76]520sub rpm_by_name :Chained('distrib_view') PathPart('rpms') {
521    my ($self, $c, $name, @subpart) = @_;
[50]522    $c->stash->{dist}{src} = 0;
[148]523    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
524        [ $c->stash->{dist}, $name ]) };
[50]525    $c->go('/404/index') unless ($c->stash->{pkgid});
[76]526    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]527}
[50]528
[190]529
530=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/by-pkgid/<PKGID>
531
532Show information about rpm having pkgid C<PKGID> for given
533C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
534
[262]535This is likelly the same thing than C</rpm/PKGID> but website will return 404
536error if the rpm is not in this distrib
[190]537
538=cut
539
[54]540sub rpm_bypkgid :Chained('distrib_view') PathPart('by-pkgid') {
[82]541    my ( $self, $c, $pkgid, @subpart ) = @_;
[54]542    if ($pkgid) {
[148]543        if (@{ $c->forward('/search/rpm/bypkgid',
544            [ $c->stash->{dist}, $pkgid ]) } ) {
[82]545            $c->go('/rpms/rpms', [ $pkgid, @subpart ]);
[55]546        } else {
547            $c->go('/404/index');
548        }
[54]549    } else {
550        $c->forward('anyrpms', [ $c->stash->{dist} ]);
551    }
[3]552}
553
554sub _media_list_rpms :Chained('distrib_view') PathPart('media') CaptureArgs(1) {
555    my ( $self, $c, $media ) = @_;
[53]556    $c->stash->{dist}{media} = $media;
[3]557}
558
[262]559=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>
560
561Return the list of rpms in media C<MEDIA> for distribution C<DISTRIB>,
562C<RELEASE>, C<ARCH>.
563
564The return list is an array of struct:
565
566    [
567        {
568            filename => 'zvbi-0.2.33-5.fc14.x86_64.rpm',
569            pkgid => 'bb9cc5113f0de3e4c7140a1ee8694900'
570        },
571        {
572            filename => 'zvbi-devel-0.2.33-5.fc14.i686.rpm',
573            pkgid => '2c3b41c5e1c475dfa31492998eb4de9f'
574        }
575    ]
576
577=cut
578
[54]579sub media_list_rpms :Chained('_media_list_rpms') PathPart('') :Args(0) {
[3]580    my ( $self, $c ) = @_;
[53]581    $c->forward('anyrpms', [ $c->stash->{dist} ]);
[3]582}
[21]583
[262]584=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/rpms/<NAME>
585
586Show binary rpm named C<NAME> in this distribution/media.
587
588Return C<404> error if such rpm does not exists
589
590=cut
591
[54]592sub media_rpm_byname :Chained('_media_list_rpms') PathPart('rpms') {
[262]593    my ( $self, $c, $name, @subpart ) = @_;
594    $c->stash->{dist}{src} = 0;
595    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
596        [ $c->stash->{dist}, $name ]) };
597    $c->go('/404/index') unless ($c->stash->{pkgid});
598    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]599}
[262]600
601=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/srpms/<NAME>
602
603Show source rpm named C<NAME> in this distribution/media.
604
605Return C<404> error if such rpm does not exists
606
607=cut
608
[54]609sub media_srpm_byname :Chained('_media_list_rpms') PathPart('srpms') {
[262]610    my ( $self, $c, $name, @subpart ) = @_;
611    $c->stash->{dist}{src} = 0;
612    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
613        [ $c->stash->{dist}, $name ]) };
614    $c->go('/404/index') unless ($c->stash->{pkgid});
615    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
[3]616}
[54]617
[262]618=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/by-pkgid/<PKGID>
619
620Show rpm having C<PKGID> in this distribution/media.
621
622Return C<404> error if such rpm does not exists
623
624=cut
625
[21]626sub media_rpm_bypkgid :Chained('_media_list_rpms') PathPart('by-pkgid') {
[76]627    my ( $self, $c, $pkgid, @part ) = @_;
[54]628    if ($pkgid) {
[148]629        if (@{ $c->forward('/search/rpm/bypkgid', [ $c->stash->{dist}, $pkgid
630            ]) } ) {
[57]631            $c->stash->{pkgid} = $pkgid;
[76]632            $c->go('/rpms/rpms', [ $pkgid, @part ]);
[55]633        } else {
634            $c->go('/404/index');
635        }
[54]636    } else {
637        $c->forward('anyrpms', [ $c->stash->{dist} ]);
638    }
[3]639}
640
[2]641=head1 AUTHOR
642
643Olivier Thauvin
644
645=head1 LICENSE
646
647This library is free software. You can redistribute it and/or modify
648it under the same terms as Perl itself.
649
650=cut
651
652__PACKAGE__->meta->make_immutable;
653
6541;
Note: See TracBrowser for help on using the repository browser.