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

Last change on this file since 272 was 272, checked in by nanardon, 13 years ago
  • add some title and keywords
File size: 17.7 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                            { 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 => $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 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
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 stored 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 release 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 architecture 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        'Available medias for ' . $distribution . ' / ' . $release . ' / ' . $arch;
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 arch 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        }
329        $c->forward('distrib_rs', [ $distribution ])
330        ->search_related('MediasPaths')
331        ->search_related('Paths')
332        ->search_related('Rpmfiles', {}, { order_by => qw(filename) })
333        ->all;
334
335    $c->stash->{xmlrpc} = $c->stash->{rpm};
336}
337
338=head2 distrib.rpms( DISTRIB )
339
340Return a list of binary packages available for C<DISTRIB>.
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
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')
382        ->search_related('Rpmfiles', {
383            pkgid => {
384                IN => $c->model('Base')->resultset('Rpms')
385                ->search({ issrc => 'false' })->get_column('pkgid') ->as_query }
386        },
387        { order_by => [ qw(filename) ] }
388        )->all ];
389
390    $c->stash->{xmlrpc} = $c->stash->{rpm};
391}
392
393=head2 distrib.srpms( DISTRIB )
394
395Return a list of sources packages available for C<DISTRIB>.
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
417sub srpms :XMLRPC {
418    my ( $self, $c, $distribution, $release, $arch ) = @_;
419
420    if (!ref $distribution) {
421        $distribution = {
422            distribution => $distribution,
423            release => $release,
424            arch => $arch,
425        }
426    }
427
428    @{$c->stash->{rpm}} = map {
429            { 
430              pkgid => $_->pkgid,
431              filename => $_->filename,
432            }
433        }
434        $c->forward('distrib_rs', [ $distribution ])
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 }
441        },
442        { order_by => [ qw(filename) ] }
443        )->all;
444
445    $c->stash->{xmlrpc} = $c->stash->{rpm};
446}
447
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
472
473=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms
474
475Return the list of available rpms for given C<DISTRIBUTION>,
476C<RELEASE>, C<ARCH>.
477
478=cut
479
480sub list_rpms :Chained('distrib_view') PathPart('rpms') Args(0) {
481    my ( $self, $c ) = @_;
482    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
483        $c->go('/404/index');
484    }
485    $c->stash->{metarevisite} = 60;
486    $c->stash->{metatitle} = sprintf(
487        'Available Rpms for %s / %s / %s',
488        $c->stash->{dist}{distribution},
489        $c->stash->{dist}{release},
490        $c->stash->{dist}{arch}
491    );
492    push(@{$c->stash->{keywords}},
493        $c->stash->{dist}{distribution},
494        $c->stash->{dist}{release},
495        $c->stash->{dist}{arch});
496    $c->forward('rpms', [ $c->stash->{dist} ]);
497}
498
499=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms
500
501Return the list of available sources rpms for given C<DISTRIBUTION>,
502C<RELEASE>, C<ARCH>.
503
504=cut
505
506sub list_srpms :Chained('distrib_view') PathPart('srpms') Args(0) {
507    my ( $self, $c ) = @_;
508    if (!$c->forward('exists', [ $c->stash->{dist} ])) {
509        $c->go('/404/index');
510    }
511    $c->stash->{metarevisite} = 60;
512    $c->stash->{metatitle} = sprintf(
513        'Available Srpms for %s / %s / %s',
514        $c->stash->{dist}{distribution},
515        $c->stash->{dist}{release},
516        $c->stash->{dist}{arch}
517    );
518    push(@{$c->stash->{keywords}},
519        $c->stash->{dist}{distribution},
520        $c->stash->{dist}{release},
521        $c->stash->{dist}{arch});
522    $c->forward('srpms', [ $c->stash->{dist} ]);
523}
524
525=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/srpms/<RPMNAME>
526
527Show the highter version of source rpm named C<RPMNAME> for given
528C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
529
530=cut
531
532sub srpm_by_name :Chained('distrib_view') PathPart('srpms') {
533    my ($self, $c, $name, @subpart) = @_;
534    $c->stash->{dist}{src} = 1;
535    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
536        [ $c->stash->{dist}, $name ]) };
537    $c->go('/404/index') unless ($c->stash->{pkgid});
538    push(@{$c->stash->{keywords}},
539        $c->stash->{dist}{distribution},
540        $c->stash->{dist}{release},
541        $c->stash->{dist}{arch});
542    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
543}
544
545=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/rpms/<RPMNAME>
546
547Show the highter version of binary rpm named C<RPMNAME> for given
548C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
549
550=cut
551
552sub rpm_by_name :Chained('distrib_view') PathPart('rpms') {
553    my ($self, $c, $name, @subpart) = @_;
554    $c->stash->{dist}{src} = 0;
555    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
556        [ $c->stash->{dist}, $name ]) };
557    $c->go('/404/index') unless ($c->stash->{pkgid});
558    push(@{$c->stash->{keywords}},
559        $c->stash->{dist}{distribution},
560        $c->stash->{dist}{release},
561        $c->stash->{dist}{arch});
562    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
563}
564
565
566=head2 Url: /distrib/<DISTRIBUTION>/<RELEASE>/<ARCH>/by-pkgid/<PKGID>
567
568Show information about rpm having pkgid C<PKGID> for given
569C<DISTRIBUTION>, C<RELEASE>, C<ARCH>.
570
571This is likelly the same thing than C</rpm/PKGID> but website will return 404
572error if the rpm is not in this distrib
573
574=cut
575
576sub rpm_bypkgid :Chained('distrib_view') PathPart('by-pkgid') {
577    my ( $self, $c, $pkgid, @subpart ) = @_;
578    if ($pkgid) {
579        if (@{ $c->forward('/search/rpm/bypkgid',
580            [ $c->stash->{dist}, $pkgid ]) } ) {
581            $c->go('/rpms/rpms', [ $pkgid, @subpart ]);
582            push(@{$c->stash->{keywords}},
583                $c->stash->{dist}{distribution},
584                $c->stash->{dist}{release},
585                $c->stash->{dist}{arch});
586        } else {
587            $c->go('/404/index');
588        }
589    } else {
590        $c->forward('anyrpms', [ $c->stash->{dist} ]);
591    }
592}
593
594sub _media_list_rpms :Chained('distrib_view') PathPart('media') CaptureArgs(1) {
595    my ( $self, $c, $media ) = @_;
596    $c->stash->{dist}{media} = $media;
597    push(@{$c->stash->{keywords}},
598        $c->stash->{dist}{distribution},
599        $c->stash->{dist}{release},
600        $c->stash->{dist}{arch},
601        $c->stash->{dist}{media},
602    );
603}
604
605=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>
606
607Return the list of rpms in media C<MEDIA> for distribution C<DISTRIB>,
608C<RELEASE>, C<ARCH>.
609
610The return list is an array of struct:
611
612    [
613        {
614            filename => 'zvbi-0.2.33-5.fc14.x86_64.rpm',
615            pkgid => 'bb9cc5113f0de3e4c7140a1ee8694900'
616        },
617        {
618            filename => 'zvbi-devel-0.2.33-5.fc14.i686.rpm',
619            pkgid => '2c3b41c5e1c475dfa31492998eb4de9f'
620        }
621    ]
622
623=cut
624
625sub media_list_rpms :Chained('_media_list_rpms') PathPart('') :Args(0) {
626    my ( $self, $c ) = @_;
627    $c->forward('anyrpms', [ $c->stash->{dist} ]);
628}
629
630=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/rpms/<NAME>
631
632Show binary rpm named C<NAME> in this distribution/media.
633
634Return C<404> error if such rpm does not exists
635
636=cut
637
638sub media_rpm_byname :Chained('_media_list_rpms') PathPart('rpms') {
639    my ( $self, $c, $name, @subpart ) = @_;
640    $c->stash->{dist}{src} = 0;
641    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
642        [ $c->stash->{dist}, $name ]) };
643    $c->go('/404/index') unless ($c->stash->{pkgid});
644    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
645}
646
647=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/srpms/<NAME>
648
649Show source rpm named C<NAME> in this distribution/media.
650
651Return C<404> error if such rpm does not exists
652
653=cut
654
655sub media_srpm_byname :Chained('_media_list_rpms') PathPart('srpms') {
656    my ( $self, $c, $name, @subpart ) = @_;
657    $c->stash->{dist}{src} = 1;
658    ($c->stash->{pkgid}) = @{ $c->forward('/search/rpm/byname',
659        [ $c->stash->{dist}, $name ]) };
660    $c->go('/404/index') unless ($c->stash->{pkgid});
661    $c->go('/rpms/rpms', [ $c->stash->{pkgid}, @subpart ]);
662}
663
664=head2 Url: /distrib/<DISTRIB>/<RELEASE>/<ARCH>/media/<MEDIA>/by-pkgid/<PKGID>
665
666Show rpm having C<PKGID> in this distribution/media.
667
668Return C<404> error if such rpm does not exists
669
670=cut
671
672sub media_rpm_bypkgid :Chained('_media_list_rpms') PathPart('by-pkgid') {
673    my ( $self, $c, $pkgid, @part ) = @_;
674    if ($pkgid) {
675        if (@{ $c->forward('/search/rpm/bypkgid', [ $c->stash->{dist}, $pkgid
676            ]) } ) {
677            $c->stash->{pkgid} = $pkgid;
678            $c->go('/rpms/rpms', [ $pkgid, @part ]);
679        } else {
680            $c->go('/404/index');
681        }
682    } else {
683        $c->forward('anyrpms', [ $c->stash->{dist} ]);
684    }
685}
686
687=head1 AUTHOR
688
689Olivier Thauvin
690
691=head1 LICENSE
692
693This library is free software. You can redistribute it and/or modify
694it under the same terms as Perl itself.
695
696=cut
697
698__PACKAGE__->meta->make_immutable;
699
7001;
Note: See TracBrowser for help on using the repository browser.