source: server/trunk/web/lib/Sophie/Controller/Chat/Cmd.pm @ 268

Last change on this file since 268 was 268, checked in by nanardon, 14 years ago
  • Property svn:keywords set to Id Rev
File size: 18.1 KB
Line 
1package Sophie::Controller::Chat::Cmd;
2use Moose;
3use namespace::autoclean;
4use Getopt::Long;
5
6BEGIN {extends 'Catalyst::Controller'; }
7
8=head1 NAME
9
10Sophie::Controller::Chat::Cmd - Catalyst Controller
11
12=head1 DESCRIPTION
13
14Catalyst Controller.
15
16=head1 METHODS
17
18=cut
19
20
21=head2 index
22
23=cut
24
25=head2 end
26
27=cut
28
29sub end : Private {
30    my ($self, $c ) = @_;
31   
32    $c->forward('/chat/update_statistic', [ ($c->action =~ /([^\/]+)$/)[0] ]);
33
34    my $reqspec = $c->req->arguments->[0];
35    $reqspec->{max_line} ||= 4;
36    my $message =  $c->stash->{xmlrpc};
37
38    my @backup = @{ $message->{message} };
39    my $needpaste = 0;
40
41    if (@{ $message->{message} } > ($reqspec->{max_line})) {
42        @{ $message->{message} } = 
43            # -2 because line 0 and we remove one for paste url
44            @backup[0 .. $reqspec->{max_line} -2];
45        $needpaste = 1;
46    } 
47
48    if ($needpaste && !$reqspec->{nopaste}) {
49        my $cmd = ($c->action =~ /([^\/]+)$/)[0];
50        my (undef, undef, @args) = @{ $c->req->arguments };
51        my $title = join(' ', $cmd, @args); 
52        my $id = $c->forward('/chat/paste', [ $title, join("\n", @backup) ]);
53        if ($id) {
54            push(@{ $message->{message} }, 'All results available here: ' . $c->uri_for('/chat', $id));
55        }
56    }
57
58    $c->stash->{xmlrpc} = $message;
59
60    $c->forward('/end');
61}
62
63=head1 BOT COMMAND
64
65=head2 REPLY
66
67=cut
68
69sub _commands {
70    my ( $self, $c ) = @_;
71    [ grep { m/^[^_]/ } map { $_->name } $self->get_action_methods() ];
72}
73
74sub _getopt : Private {
75    my ( $self, $c, $options, @args) = @_;
76
77    local @ARGV = @args;
78
79    GetOptions(%{ $options || {} });
80
81    return \@ARGV;
82}
83
84sub _fmt_location : Private {
85    my ($self, $c, $searchspec, $pkgid) = @_;
86
87    my @loc;
88    foreach (@{ $c->forward('/rpms/location', [ $pkgid ]) }) {
89        push @loc, sprintf(
90            '%s (%s, %s, %s)',
91            $_->{media},
92            $_->{dist} || $_->{distribution},
93            $_->{release},
94            $_->{arch},
95        );
96    }
97    return join(', ', @loc);
98}
99
100sub _find_rpm_elsewhere : Private {
101    my ($self, $c, $searchspec, $name) = @_;
102    if ($searchspec->{distribution}) {
103        my $rpmlist = $c->forward('/search/rpm/byname', [ 
104                {
105                    distribution => $searchspec->{distribution},
106                    src => $searchspec->{src},
107                    rows => 1,
108                }, $name ]);
109        if (@{$rpmlist}) {
110            return $c->forward('_fmt_location', [ { 
111                        distribution => $searchspec->{distribution}
112                    }, $rpmlist->[0] ]);
113        }
114    }
115    my $rpmlist = $c->forward('/search/rpm/byname', [ { src =>
116                $searchspec->{src}}, $name ]);
117    my %dist;
118    foreach(@$rpmlist) {
119        foreach (@{ $c->forward('/rpms/location', [ $_ ]) }) {
120            $dist{$_->{dist} || $_->{distribution}} = 1;
121        }
122    }
123    if (keys %dist) {
124        return join(', ', sort keys %dist);
125    }
126    return;
127}
128
129=head1 AVAILABLE FUNCTIONS
130
131=cut
132
133=head2 help [cmd]
134
135Return help about command cmd or list available command.
136
137=cut
138
139sub help : XMLRPC {
140    my ( $self, $c, $reqspec, $cmd ) = @_;
141    if ($cmd) {
142        my @message = grep { /\S+/ } split(/\n/,
143            $c->model('Help::POD')->bot_help_text($cmd) || 'No help available');
144        return $c->{stash}->{xmlrpc} = {
145            private_reply => 1,
146            message => \@message,
147        };
148    } else {
149        return $c->{stash}->{xmlrpc} = {
150            private_reply => 1,
151            message => [
152                'available command:',
153                join(', ', sort grep { $_ !~ /^end$/ } @{ $self->_commands }),
154                'Find more at ' . $c->uri_for('/help/chat'),
155            ],
156        }
157    }
158}
159
160=head2 asv
161
162ASV means in french "age, sexe, ville" (age, sex and town).
163Return the version of the Chat module version.
164
165=cut
166
167sub asv : XMLRPC {
168    my ( $self, $c ) = @_;
169    return $c->stash->{xmlrpc} = {
170        message => [ 'Sophie: ' . $Sophie::VERSION . ', Chat ' . q$Rev$ ],
171    };
172}
173
174=head2 q REGEXP
175
176Search rpm name matching C<REGEXP>.
177
178NB: C<.>, C<*>, C<+> have special meaning
179and have to be escaped.
180
181=cut
182
183sub q : XMLRPC {
184    my ($self, $c, $reqspec, @args) = @_;
185
186    $reqspec->{src} = 0;
187
188    @args = @{ $c->forward('_getopt', [
189        {
190            'd=s' => \$reqspec->{distribution},
191            'v=s' => \$reqspec->{release},
192            'a=s' => \$reqspec->{arch},
193            's'   => sub { $reqspec->{src} = 1 },
194        }, @args ]) };
195
196    my $res = $c->forward('/search/tags/name_regexp', $reqspec, $args[0]);
197    warn join(' ', @{ $res });
198    if (!@{ $res }) {
199        return $c->stash->{xmlrpc} = {
200            message => [ 'Nothing match `' . $args[0] . '\'' ]
201        };
202    } else {
203        my @message = 'rpm name matching `' . $args[0] . '\':';
204        while (@{ $res }) {
205            my $str = '';
206            while (length($str) < 70) {
207                my $item = shift(@{ $res }) or last;
208                $str .= ', ' if ($str);
209                $str .= $item->{name};
210            }
211            push(@message, $str);
212        }
213        return $c->stash->{xmlrpc} = {
214            message => \@message,
215        };
216    }
217}
218
219=head2 version [-s] NAME
220
221Show the version of package C<NAME>.
222
223=cut
224
225sub version : XMLRPC {
226    my ($self, $c, $reqspec, @args) = @_;
227
228    my @message;
229    $reqspec->{src} = 0;
230
231    @args = @{ $c->forward('_getopt', [
232        {
233            'd=s' => \$reqspec->{distribution},
234            'v=s' => \$reqspec->{release},
235            'a=s' => \$reqspec->{arch},
236            's'   => sub { $reqspec->{src} = 1 },
237        }, @args ]) };
238
239    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
240        return $c->stash->{xmlrpc} = {
241            message => [ "I don't have such distribution" ]
242        };
243    }
244
245    my $rpmlist = $c->forward('/search/rpm/byname', [ $reqspec, $args[0] ]);
246    if (!@{ $rpmlist }) {
247        my $else = $c->forward('_find_rpm_elsewhere', [ $reqspec, $args[0] ]);
248        if ($else) {
249            return $c->stash->{xmlrpc} = {
250                message => [ 
251                    "There is no rpm named `$args[0]', but the word matches in " . $else
252                ],
253            }
254        } else {
255            return $c->stash->{xmlrpc} = {
256                message => [ "The rpm named `$args[0]' has not been found" ],
257            }
258        }
259    }
260    foreach (@{ $rpmlist }) {
261        my $info = $c->forward('/rpms/basicinfo', [ $_ ]);
262        push @message, $info->{evr} . ' // ' .
263            $c->forward('_fmt_location', [ $reqspec, $_ ]);
264    }
265    return $c->stash->{xmlrpc} = {
266        message => \@message,
267    }
268}
269
270=head2 v
271
272C<v> is an alias for L<version> command.
273
274=cut
275
276sub v : XMLRPC {
277    my ($self, $c, @args) = @_;
278    $c->forward('version', [ @args ]);
279}
280
281=head2 summary [-s] NAME
282
283Show the summary of package C<NAME>.
284
285=cut
286
287sub summary : XMLRPC {
288    my ($self, $c, $reqspec, @args) = @_;
289
290    $c->forward('qf', [ $reqspec, @args, '%{summary}' ]);
291}
292
293=head2 s
294
295Is an alias for C<summary> command.
296
297=cut
298
299sub s : XMLRPC {
300    my ($self, $c, @args) = @_;
301    $c->forward('summary', [ @args ]);
302}
303
304=head2 packager [-s] NAME
305
306Show the packager of package C<NAME>.
307
308=cut
309
310sub packager : XMLRPC {
311    my ($self, $c, $reqspec, @args) = @_;
312
313    $c->forward('qf', [ $reqspec, @args, '%{packager}' ]);
314}
315
316=head2 p
317
318Is an alias for C<packager> command.
319
320=cut
321
322sub p : XMLRPC {
323    my ($self, $c, @args) = @_;
324    $c->forward('packager', [ @args ]);
325}
326
327=head2 arch [-s] NAME
328
329Show the architecture of package C<NAME>.
330
331=cut 
332
333sub arch : XMLRPC {
334    my ($self, $c, $reqspec, @args) = @_;
335
336    $c->forward('qf', [ $reqspec, @args, '%{arch}' ]);
337}
338
339=head2 a
340
341Is an alias to C<arch> command.
342
343=cut 
344
345sub a : XMLRPC {
346    my ($self, $c, @args) = @_;
347    $c->forward('arch', [ @args ]);
348}
349
350=head2 url [-s] NAME
351
352Show the url of package C<NAME>.
353
354=cut 
355
356sub url : XMLRPC {
357    my ($self, $c, $reqspec, @args) = @_;
358
359    $c->forward('qf', [ $reqspec, @args, '%{url}' ]);
360}
361
362=head2 u
363
364Is an alias to C<url> command.
365
366=cut 
367
368sub u : XMLRPC {
369    my ($self, $c, @args) = @_;
370    $c->forward('url', [ @args ]);
371}
372
373=head2 group [-s] NAME
374
375Show the group of package C<NAME>.
376
377=cut 
378
379sub group : XMLRPC {
380    my ($self, $c, $reqspec, @args) = @_;
381
382    $c->forward('qf', [ $reqspec, @args, '%{group}' ]);
383}
384
385=head2 g
386
387Is an alias to C<group> command.
388
389=cut 
390
391sub g : XMLRPC {
392    my ($self, $c, @args) = @_;
393    $c->forward('group', [ @args ]);
394}
395
396=head2 license [-s] NAME
397
398Show the license of package C<NAME>.
399
400=cut 
401
402sub license : XMLRPC {
403    my ($self, $c, $reqspec, @args) = @_;
404
405    $c->forward('qf', [ $reqspec, @args, '%{license}' ]);
406}
407
408=head2 l
409
410Is an alias to C<license> command.
411
412=cut 
413
414sub l : XMLRPC {
415    my ($self, $c, @args) = @_;
416    $c->forward('license', [ @args ]);
417}
418
419=head2 buildtime [-s] NAME
420
421Show the build time of package C<NAME>.
422
423=cut
424
425sub buildtime : XMLRPC {
426    my ($self, $c, $reqspec, @args) = @_;
427
428    $c->forward('qf', [ $reqspec, @args, '%{buildtime:date}' ]);
429}
430
431=head2 builddate
432
433Is an alias for C<buildtime> command.
434
435=cut
436
437sub builddate : XMLRPC {
438    my ($self, $c, @args) = @_;
439    $c->forward('buildtime', [ @args ]);
440}
441
442=head2 builddate
443
444Is an alias for C<buildtime> command.
445
446=cut
447
448sub b : XMLRPC {
449    my ($self, $c, @args) = @_;
450    $c->forward('builddate', [ @args ]);
451}
452
453=head2 cookie [-s] NAME
454
455Show the C<cookie> tag of package C<NAME>.
456
457=cut
458
459sub cookie : XMLRPC {
460    my ($self, $c, $reqspec, @args) = @_;
461
462    $c->forward('qf', [ $reqspec, @args, '%{cookie}' ]);
463}
464
465=head2 sourcerpm NAME
466
467Show the C<sourcerpm> tag of package C<NAME>.
468
469=cut
470
471sub sourcerpm : XMLRPC {
472    my ($self, $c, $reqspec, @args) = @_;
473
474    $c->forward('qf', [ $reqspec, @args, '%{sourcerpm}' ]);
475}
476
477=head2 src NAME
478
479Is an alias for C<sourcerpm> command.
480
481=cut
482
483sub src : XMLRPC {
484    my ($self, $c, $reqspec, @args) = @_;
485
486    $c->forward('sourcerpm', [ $reqspec, @args ]);
487}
488
489=head2 qf rpmname format
490
491Perform an rpm -q --qf on package named C<rpmname>
492
493=cut
494
495sub qf : XMLRPC {
496    my ($self, $c, $reqspec, @args) = @_;
497    my @message;
498    $reqspec->{src} = 0;
499
500    @args = @{ $c->forward('_getopt', [
501        {
502            'd=s' => \$reqspec->{distribution},
503            'v=s' => \$reqspec->{release},
504            'a=s' => \$reqspec->{arch},
505            's'   => sub { $reqspec->{src} = 1 },
506        }, @args ]) };
507
508    @args == 2 or do {
509        $c->error('No argument given');
510        return;
511    };
512
513    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
514        return $c->stash->{xmlrpc} = {
515            message => [ "I don't have such distribution" ]
516        };
517    }
518
519    my $rpmlist = $c->forward('/search/rpm/byname', [ $reqspec, $args[0] ]);
520    if (!@{ $rpmlist }) {
521        my $else = $c->forward('_find_rpm_elsewhere', [ $reqspec, $args[0] ]);
522        if ($else) {
523            return $c->stash->{xmlrpc} = {
524                message => [ 
525                    "There is no rpm named `$args[0]', but the word matches in " . $else
526                ],
527            }
528        } else {
529            return $c->stash->{xmlrpc} = {
530                message => [ "The rpm named `$args[0]' has not been found" ],
531            }
532        }
533    }
534    foreach (@{ $rpmlist }) {
535        my $info = $c->forward('/rpms/queryformat', [ $_, $args[1] ]);
536        push @message, $info . ' // ' .
537            $c->forward('_fmt_location', [ $reqspec, $_ ]);
538    }
539    return $c->stash->{xmlrpc} = {
540        message => \@message,
541    }
542}
543
544=head2 more NAME
545
546Show url where details about package named C<NAME> can be found
547
548=cut
549
550sub more : XMLRPC {
551    my ($self, $c, $reqspec, @args) = @_;
552    my @message;
553    $reqspec->{src} = 0;
554
555    @args = @{ $c->forward('_getopt', [
556        {
557            'd=s' => \$reqspec->{distribution},
558            'v=s' => \$reqspec->{release},
559            'a=s' => \$reqspec->{arch},
560            's'   => sub { $reqspec->{src} = 1 },
561        }, @args ]) };
562
563    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
564        return $c->stash->{xmlrpc} = {
565            message => [ "I don't have such distribution" ]
566        };
567    }
568
569    my $rpmlist = $c->forward('/search/rpm/byname', [ $reqspec, $args[0] ]);
570    if (!@{ $rpmlist }) {
571        my $else = $c->forward('_find_rpm_elsewhere', [ $reqspec, $args[0] ]);
572        if ($else) {
573            return $c->stash->{xmlrpc} = {
574                message => [ 
575                    "There is no rpm named `$args[0]', but the word matches in " . $else
576                ],
577            }
578        } else {
579            return $c->stash->{xmlrpc} = {
580                message => [ "The rpm named `$args[0]' has not been found" ],
581            }
582        }
583    }
584    foreach (@{ $rpmlist }) {
585        push @message, $c->uri_for('/rpms', $_) . ' // ' .
586            $c->forward('_fmt_location', [ $reqspec, $_ ]);
587    }
588    return $c->stash->{xmlrpc} = {
589        message => \@message,
590    }
591}
592
593=head2 buildfrom NAME
594
595Return the list of package build from source package named C<NAME>
596
597=cut
598
599sub buildfrom : XMLRPC {
600    my ($self, $c, $reqspec, @args) = @_;
601    $reqspec->{src} = 1;
602    my @message;
603    @args = @{ $c->forward('_getopt', [
604        {
605            'd=s' => \$reqspec->{distribution},
606            'v=s' => \$reqspec->{release},
607            'a=s' => \$reqspec->{arch},
608        }, @args ]) };
609    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
610        return $c->stash->{xmlrpc} = {
611            message => [ "I don't have such distribution" ]
612        };
613    }
614    my $rpmlist = $c->forward('/search/rpm/byname', [ $reqspec, $args[0] ]);
615    if (!@{ $rpmlist }) {
616        my $else = $c->forward('_find_rpm_elsewhere', [ $reqspec, $args[0] ]);
617        if ($else) {
618            return $c->stash->{xmlrpc} = {
619                message => [ 
620                    "There is no rpm named `$args[0]', but the word matches in " . $else
621                ],
622            }
623        } else {
624            return $c->stash->{xmlrpc} = {
625                message => [ "The rpm named `$args[0]' has not been found" ],
626            }
627        }
628    }
629    foreach (@{ $rpmlist }) {
630        my $res = $c->forward('/rpms/binaries', [ $_ ]);
631        my @name;
632        foreach (@$res) {
633            push(@name, $c->forward('/rpms/basicinfo', [ $_ ])->{name});
634        }
635        push(@message, join(', ', sort @name));
636    }
637    return $c->stash->{xmlrpc} = {
638        message => \@message,
639    }
640
641}
642
643=head2 findfile FILE
644
645Return the rpm owning the file C<FILE>.
646
647=cut
648
649sub findfile : XMLRPC {
650    my ($self, $c, $reqspec, @args) = @_;
651
652    my @message;
653    $reqspec->{src} = 0;
654
655    @args = @{ $c->forward('_getopt', [
656        {
657            'd=s' => \$reqspec->{distribution},
658            'v=s' => \$reqspec->{release},
659            'a=s' => \$reqspec->{arch},
660        }, @args ]) };
661
662    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
663        return $c->stash->{xmlrpc} = {
664            message => [ "I don't have such distribution" ]
665        };
666    }
667
668    my $rpmlist = $c->forward('/search/rpm/byfile', [ $reqspec, $args[0] ]);
669    if (!@{ $rpmlist }) {
670        return $c->stash->{xmlrpc} = {
671            message => [ "Sorry, no file $args[0] found" ],
672        }
673    } elsif (@{ $rpmlist } > 20) {
674        foreach (@{ $rpmlist }) {
675            my $info = $c->forward('/rpms/basicinfo', [ $_ ]);
676            push @message, $info->{name} . ' // ' .
677                $c->forward('_fmt_location', [ $reqspec, $_ ]);
678        }
679        return $c->stash->{xmlrpc} = {
680            message => \@message,
681        }
682    } else {
683        my %list;
684        foreach (@{ $rpmlist }) {
685            my $info = $c->forward('/rpms/basicinfo', [ $_ ]);
686            $list{$info->{name}} = 1;
687        }
688        return $c->stash->{xmlrpc} = {
689            message => [ join(', ', sort keys %list) ],
690        };
691    }
692}
693
694sub what : XMLRPC {
695    my ($self, $c, $reqspec, @args) = @_;
696       
697    @args = @{ $c->forward('_getopt', [
698        {
699            'd=s' => \$reqspec->{distribution},
700            'v=s' => \$reqspec->{release},
701            'a=s' => \$reqspec->{arch},
702            's'   => \$reqspec->{src},
703        }, @args ]) };
704
705    my ($type, $depname, $sense, $evr) = @args;
706
707    my $deptype = uc(substr($type, 0, 1));
708    my $rpmlist = $c->forward('/search/rpm/bydep',
709        [ $reqspec, $deptype, $depname, $sense, $evr ]);
710
711    if (@{ $rpmlist } < 20) {
712        my @name;
713        foreach (@{ $rpmlist }) {
714            my $info = $c->forward('/rpms/basicinfo', [ $_ ]);
715            push @name, $info->{name} . '-' . $info->{evr};
716        }
717        return $c->stash->{xmlrpc} = {
718            message => [
719                "Package matching $depname" . ($evr ? " $sense $evr" : '') .
720                ':', 
721                join(' ', @name),
722            ],
723        }
724    } else {
725        return $c->stash->{xmlrpc} = {
726            message => [ 'Too many result' ],
727        };
728    }
729
730}
731
732=head2 maint RPMNAME
733
734Show the maintainers for the rpm named C<RPMNAME>.
735
736=cut
737
738sub maint : XMLRPC {
739    my ($self, $c, $reqspec, @args) = @_;
740    $reqspec->{src} = 0;
741    my @message;
742    @args = @{ $c->forward('_getopt', [
743        {
744            'd=s' => \$reqspec->{distribution},
745            'v=s' => \$reqspec->{release},
746            'a=s' => \$reqspec->{arch},
747        }, @args ]) };
748    if (!$c->forward('/distrib/exists', [ $reqspec ])) {
749        return $c->stash->{xmlrpc} = {
750            message => [ "I don't have such distribution" ]
751        };
752    }
753    my $rpmlist = $c->forward('/search/rpm/byname', [ $reqspec, $args[0] ]);
754    if (!@{ $rpmlist }) {
755        my $else = $c->forward('_find_rpm_elsewhere', [ $reqspec, $args[0] ]);
756        if ($else) {
757            return $c->stash->{xmlrpc} = {
758                message => [ 
759                    "There is no rpm named `$args[0]', but the word matches in " . $else
760                ],
761            }
762        } else {
763            return $c->stash->{xmlrpc} = {
764                message => [ "The rpm named `$args[0]' has not been found" ],
765            }
766        }
767    }
768    my %maint;
769    foreach (@{ $rpmlist }) {
770        my $res = $c->forward('/rpms/maintainers', [ $_ ]);
771        foreach (@$res) {
772            my $m = 'For ' . $_->{vendor} . ': ' . $_->{owner};
773            $maint{$m} = 1;
774        }
775    }
776    return $c->stash->{xmlrpc} = {
777        message => [ sort keys %maint ],
778    }
779}
780
781=head1 AUTHOR
782
783Olivier Thauvin
784
785=head1 LICENSE
786
787This library is free software. You can redistribute it and/or modify
788it under the same terms as Perl itself.
789
790=cut
791
792__PACKAGE__->meta->make_immutable;
793
7941;
Note: See TracBrowser for help on using the repository browser.