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
Line 
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
19=head2 distrib.list( [ DISTRIBUTION [, RELEASE [, ARCH ]]]
20
21List content of distrib according arguments given. IE list available
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
30sub list :XMLRPC {
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
44    my $rs = $c->model('Base')->resultset('Distribution');
45    if (!$distribution) {
46        return $c->stash->{xmlrpc} = [ map { $_->name }
47            $rs->search(undef, { order_by => ['name'] })->all ];
48    }
49    $rs = $rs->search({
50            -or => [
51                { name      => $distribution },
52                { shortname => $distribution },
53            ],
54        })->search_related('Release');
55    if (!$release) {
56        return $c->stash->{xmlrpc} = [ map { $_->version }
57            $rs->search(undef, { order_by => ['version'] })->all ];
58    }
59    $rs = $rs->search({ version => $release })->search_related('Arch');
60    if (!$arch) {
61        return $c->stash->{xmlrpc} = [ map { $_->arch } 
62            $rs->search(undef, { order_by => ['arch'] })->all ];
63    }
64    $rs = $rs->search({ arch => $arch })->search_related('Medias');
65    return $c->stash->{xmlrpc} = [ map { $_->label }
66        $rs->search(undef, { order_by => ['label'] })->all ];
67}
68
69sub struct :XMLRPC {
70    my ( $self, $c, $distribution, $release, $arch ) = @_;
71
72    if (!ref $distribution) {
73        $distribution = {
74            distribution => $distribution,
75            release => $release,
76            arch => $arch,
77        }
78    }
79
80    my $rs = $c->forward('distrib_rs', [ $distribution ])
81        ->search({}, { order_by => 'label' });
82    $c->stash->{xmlrpc} = [ map { 
83        { 
84            label => $_->label,
85            group_label => $_->group_label,
86        } 
87    } $rs->all ];
88}
89
90sub distrib_rs : Private {
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
101    return $c->model('Base')->resultset('Distribution')
102        ->search(
103            {
104                $distrib->{distribution}
105                    ? (-or => [
106                            { 'me.name' =>      $distrib->{distribution} },
107                            { shortname => $distrib->{distribution} },
108                        ],
109                    )
110                    : ()
111            },
112            {
113                select => [ qw(name shortname) ],
114            }
115        )->search_related('Release',
116            {
117                $distrib->{release}
118                    ? (version => $distrib->{release})
119                    : ()
120            },
121            {
122                select => [ qw(version) ],
123            }
124        )->search_related('Arch',
125            {
126                $distrib->{arch}
127                    ? ('Arch.arch' => $distrib->{arch})
128                    : ()
129            },
130            {
131                select => [ qw(arch) ],
132            }
133        )->search_related('Medias',
134            {
135                ($distrib->{media} ? (label => $distrib->{media}) : ()),
136                ($distrib->{media_group}
137                    ? (group_label => $distrib->{media_group})
138                    : ()),
139            },
140            {
141                select => [ qw(label group_label) ],
142            }
143        );
144}
145
146=head2 distrib.exists( DISTRIB )
147
148Return true or false if distribution 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 useful to check if a search have chance to succeed, eg if the
169user is not searching a rpm on a non existing distribution.
170
171=cut
172
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
185=head2 index
186
187=cut
188
189=head2 Url: /distrib
190
191Return the list of currently indexed distributions.
192
193=cut
194
195sub index :Path :Chained :Args(0)  {
196    my ( $self, $c ) = @_;
197
198    $c->stash->{metarevisite} = 60;
199    $c->stash->{metatitle} = 'Available Distribution';
200    push(@{$c->stash->{keywords}}, 'Rpm Distribution');
201    $c->forward('list');
202}
203
204=head2 release
205
206=cut
207
208=head2 Url: /distrib/<DISTRIBUTION>
209
210Return the list of available releases for given C<DISTRIBUTION>.
211
212=cut
213
214sub list_release :Path :Args(1) {
215    my ( $self, $c, $distribution ) = @_;
216    $c->stash->{dist}{distribution} = $distribution;
217    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
218        $c->go('/404/index');
219    }
220    $c->stash->{metarevisite} = 60;
221    $c->stash->{metatitle} = 'Available release for ' . $distribution;
222    push(@{$c->stash->{keywords}}, $distribution);
223    $c->forward('list', [ $c->stash->{dist} ] );
224}
225
226=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>
227
228Return the list of available architectures for given C<DISTRIBUTION>,
229C<RELEASE>.
230
231=cut
232
233sub list_arch :Path :Args(2) {
234    my ( $self, $c, $distribution, $release ) = @_;
235
236    # Compatability with Sophie1
237    if ($distribution =~ /^([^,]+,)?[^,]+,[^,]+$/) {
238        $c->go('/compat/distrib', [ $distribution, $release ]);
239    }
240
241    $c->stash->{dist}{distribution} = $distribution;
242    $c->stash->{dist}{release} = $release;
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);
250    $c->forward('list', [ $c->stash->{dist} ] );
251}
252
253
254sub distrib_view :PathPrefix :Chained :CaptureArgs(3) {
255    my ( $self, $c, $distribution, $release, $arch ) = @_;
256    $c->stash->{dist}{distribution} = $distribution;
257    $c->stash->{dist}{release} = $release;
258    $c->stash->{dist}{arch} = $arch;
259    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
260        $c->go('/404/index');
261    }
262    $c->stash->{metarevisite} = 60;
263    $c->stash->{metatitle} =
264        $distribution . ' / ' . $release . ' / ' . $arch . ' content';
265    push(@{$c->stash->{keywords}}, $distribution, $release, $arch);
266    $c->stash->{distrib} = $c->stash->{dist};
267}
268
269=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>
270
271Return the list of available medias for given C<DISTRIBUTION>,
272C<RELEASE>, C<ARCH>.
273
274=cut
275
276sub distrib :Chained('distrib_view') PathPart('') :Args(0) {
277    my ( $self, $c ) = @_;
278    $c->forward('list', [ $c->stash->{dist} ]);
279}
280
281# Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/media
282
283sub media :Chained('/distrib/distrib_view') PathPart('media') :Args(0) {
284    my ( $self, $c ) = @_;
285    $c->forward('struct', [ $c->stash->{dist} ]);
286}
287
288=head2 distrib.anyrpms( DISTRIB )
289
290Return a list of packages available for C<DISTRIB>.
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 archictecture name
307
308=back
309
310=cut
311
312sub anyrpms :XMLRPC {
313    my ( $self, $c, $distribution, $release, $arch ) = @_;
314
315    if (!ref $distribution) {
316        $distribution = {
317            distribution => $distribution,
318            release => $release,
319            arch => $arch,
320        }
321    }
322
323    $c->stash->{rpm} = [ map {
324        {
325        pkgid => $_->pkgid,
326        filename => $_->filename,
327        }
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 ];
336
337    $c->stash->{xmlrpc} = $c->stash->{rpm};
338}
339
340=head2 distrib.rpms( DISTRIB )
341
342Return a list of binary packages available for C<DISTRIB>.
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
358The architecture name
359
360=back
361
362=cut
363
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
375    $distribution->{src} = 0;
376
377    $c->stash->{rpm} = [ map {
378        {
379        pkgid => $_->pkgid,
380        filename => $_->filename,
381        }
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 ];
390
391    $c->stash->{xmlrpc} = $c->stash->{rpm};
392}
393
394=head2 distrib.srpms( DISTRIB )
395
396Return a list of source packages available for C<DISTRIB>.
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
412The architecture name
413
414=back
415
416=cut
417
418sub srpms :XMLRPC {
419    my ( $self, $c, $distribution, $release, $arch ) = @_;
420
421    if (!ref $distribution) {
422        $distribution = {
423            distribution => $distribution,
424            release => $release,
425            arch => $arch,
426        }
427    }
428
429    $distribution->{src} = 1;
430
431    $c->stash->{rpm} = [ map {
432        {
433        pkgid => $_->pkgid,
434        filename => $_->filename,
435        }
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 ];
444
445    $c->stash->{xmlrpc} = $c->stash->{rpm};
446}
447
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
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
496
497=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms
498
499Return the list of available rpms for given C<DISTRIBUTION>,
500C<RELEASE>, C<ARCH>.
501
502=cut
503
504sub list_rpms :Chained('distrib_view') PathPart('rpms') Args(0) {
505    my ( $self, $c ) = @_;
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});
520    $c->forward('rpms', [ $c->stash->{dist} ]);
521}
522
523=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms
524
525Return the list of available source rpms for given C<DISTRIBUTION>,
526C<RELEASE>, C<ARCH>.
527
528=cut
529
530sub list_srpms :Chained('distrib_view') PathPart('srpms') Args(0) {
531    my ( $self, $c ) = @_;
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});
546    $c->forward('srpms', [ $c->stash->{dist} ]);
547}
548
549=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms/<RPMNAME>
550
551Show the highest version of source rpm named C<RPMNAME> for given
552C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
553
554=cut
555
556sub srpm_by_name :Chained('distrib_view') PathPart('srpms') {
557    my ($self, $c, $name, @subpart) = @_;
558    $c->stash->{dist}{src} = 1;
559    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
560        [ $c->stash->{dist}, $name ]) };
561    $c->go('/404/index') unless ($c->stash->{pkgid});
562    push(@{$c->stash->{keywords}},
563        $c->stash->{dist}{distribution},
564        $c->stash->{dist}{release},
565        $c->stash->{dist}{arch});
566    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
567}
568
569=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms/<RPMNAME>
570
571Show the highest version of binary rpm named C<RPMNAME> for given
572C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
573
574=cut
575
576sub rpm_by_name :Chained('distrib_view') PathPart('rpms') {
577    my ($self, $c, $name, @subpart) = @_;
578    $c->stash->{dist}{src} = 0;
579    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
580        [ $c->stash->{dist}, $name ]) };
581    $c->go('/404/index') unless ($c->stash->{pkgid});
582    push(@{$c->stash->{keywords}},
583        $c->stash->{dist}{distribution},
584        $c->stash->{dist}{release},
585        $c->stash->{dist}{arch});
586    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
587}
588
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
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
597
598=cut
599
600sub rpm_bypkgid :Chained('distrib_view') PathPart('by-pkgid') {
601    my ( $self, $c, $pkgid, @subpart ) = @_;
602    if ($pkgid) {
603        if (@{ $c->forward('/search/rpm/bypkgid',
604            [ $c->stash->{dist}, $pkgid ]) } ) {
605            $c->go('/rpms/rpms', [ $pkgid, @subpart ]);
606            push(@{$c->stash->{keywords}},
607                $c->stash->{dist}{distribution},
608                $c->stash->{dist}{release},
609                $c->stash->{dist}{arch});
610        } else {
611            $c->go('/404/index');
612        }
613    } else {
614        $c->forward('anyrpms', [ $c->stash->{dist} ]);
615    }
616}
617
618sub _media_list_rpms :Chained('distrib_view') PathPart('media') CaptureArgs(1) {
619    my ( $self, $c, $media ) = @_;
620    $c->stash->{dist}{media} = $media;
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    );
627}
628
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
634The result list is an array of struct:
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
649sub media_list_rpms :Chained('_media_list_rpms') PathPart('') :Args(0) {
650    my ( $self, $c ) = @_;
651    $c->forward('anyrpms', [ $c->stash->{dist} ]);
652}
653
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
662sub media_rpm_byname :Chained('_media_list_rpms') PathPart('rpms') {
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 ]);
669}
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
679sub media_srpm_byname :Chained('_media_list_rpms') PathPart('srpms') {
680    my ( $self, $c, $name, @subpart ) = @_;
681    $c->stash->{dist}{src} = 1;
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 ]);
686}
687
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
696sub media_rpm_bypkgid :Chained('_media_list_rpms') PathPart('by-pkgid') {
697    my ( $self, $c, $pkgid, @part ) = @_;
698    if ($pkgid) {
699        if (@{ $c->forward('/search/rpm/bypkgid', [ $c->stash->{dist}, $pkgid
700            ]) } ) {
701            $c->stash->{pkgid} = $pkgid;
702            $c->go('/rpms/rpms', [ $pkgid, @part ]);
703        } else {
704            $c->go('/404/index');
705        }
706    } else {
707        $c->forward('anyrpms', [ $c->stash->{dist} ]);
708    }
709}
710
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.