root/lang/perl/Acme-CPANAuthors/trunk/lib/Acme/CPANAuthors.pm @ 32700

Revision 32700, 6.5 kB (checked in by charsbar, 4 years ago)

Acme-CPANAuthers: added more lists to the pod; $VERSION in ::Utils; 0.08 -> CPAN

  • Property svn:eol-style set to native
Line 
1package Acme::CPANAuthors;
2
3use strict;
4use warnings;
5use Carp;
6use Acme::CPANAuthors::Utils qw( cpan_authors cpan_packages );
7
8our $VERSION = '0.08';
9
10sub new {
11  my ($class, @categories) = @_;
12
13  @categories = _list_categories() unless @categories;
14
15  my %authors;
16  foreach my $category ( @categories ) {
17    %authors = ( %authors, _get_authors_of($category) );
18  }
19  bless \%authors, $class;
20}
21
22sub count {
23  my $self = shift;
24
25  return scalar keys %{ $self };
26}
27
28sub id {
29  my ($self, $id) = @_;
30
31  unless ( $id ) {
32    return sort keys %{ $self };
33  }
34  else {
35    return $self->{$id} ? 1 : 0;
36  }
37}
38
39sub name {
40  my ($self, $id) = @_;
41
42  unless ( $id ) {
43    return sort values %{ $self };
44  }
45  else {
46    return $self->{$id};
47  }
48}
49
50sub distributions {
51  my ($self, $id) = @_;
52
53  return unless $id;
54
55  my @packages;
56  foreach my $package ( cpan_packages->distributions ) {
57    if ( $package->cpanid eq $id ) {
58      push @packages, $package;
59    }
60  }
61
62  return @packages;
63}
64
65sub latest_distributions {
66  my ($self, $id) = @_;
67
68  return unless $id;
69
70  my @packages;
71  foreach my $package ( cpan_packages->latest_distributions ) {
72    if ( $package->cpanid eq $id ) {
73      push @packages, $package;
74    }
75  }
76
77  return @packages;
78}
79
80sub avatar_url {
81  my ($self, $id, %options) = @_;
82
83  return unless $id;
84
85  require Gravatar::URL;
86  my $author = cpan_authors->author($id) or return;
87
88  return Gravatar::URL::gravatar_url( email => $author->email, %options );
89}
90
91sub kwalitee {
92  my ($self, $id) = @_;
93
94  return unless $id;
95
96  require Acme::CPANAuthors::Utils::Kwalitee;
97  return  Acme::CPANAuthors::Utils::Kwalitee->fetch($id);
98}
99
100sub look_for {
101  my ($self, $id_or_name) = @_;
102
103  return unless defined $id_or_name;
104  unless (ref $id_or_name eq 'Regexp') {
105    $id_or_name = qr/$id_or_name/i;
106  }
107
108  my @found;
109  foreach my $category ( _list_categories() ) {
110    my %authors = _get_authors_of($category);
111    while ( my ($id, $name) = each %authors ) {
112      if ($id =~ /$id_or_name/ or $name =~ /$id_or_name/) {
113        push @found, {
114          id       => $id,
115          name     => $name,
116          category => $category,
117        };
118      }
119    }
120  }
121  return @found;
122}
123
124sub _list_categories {
125  require Module::Find;
126  return grep { $_ !~ /^(?:Register|Utils|Not)$/ }
127         map  { s/^Acme::CPANAuthors:://; $_ }
128         Module::Find::findsubmod( 'Acme::CPANAuthors' );
129}
130
131sub _get_authors_of {
132  my $category = shift;
133
134  $category =~ s/^Acme::CPANAuthors:://;
135
136  return if $category =~ /^(?:Register|Utils)$/;
137
138  my $package = "Acme::CPANAuthors\::$category";
139  eval "require $package";
140  if ( $@ ) {
141    carp "$category CPAN Authors are not registered yet: $@";
142    return;
143  }
144  $package->authors;
145}
146
1471;
148
149__END__
150
151=head1 NAME
152
153Acme::CPANAuthors - We are CPAN authors
154
155=head1 SYNOPSIS
156
157    use Acme::CPANAuthors;
158
159    my $authors = Acme::CPANAuthors->new('Japanese');
160
161    my $number   = $authors->count;
162    my @ids      = $authors->id;
163    my @distros  = $authors->distributions('ISHIGAKI');
164    my $url      = $authors->avatar_url('ISHIGAKI');
165    my $kwalitee = $authors->kwalitee('ISHIGAKI');
166    my @info     = $authors->look_for('ishigaki');
167
168  If you don't like this interface, just use a specific authors list.
169
170    use Acme::CPANAuthors::Japanese;
171
172    my %authors = Acme::CPANAuthors::Japanese->authors;
173
174    # note that ->author is context sensitive.
175    # however, you can't write this without dereference
176    # as "keys" checks the type (actually, the number) of args.
177    for my $name (keys %{ Acme::CPANAuthors::Japanese->authors }) {
178      print Acme::CPANAuthors::Japanese->authors->{$name}, "\n";
179    }
180
181=head1 DESCRIPTION
182
183Sometimes we just want to know something to confirm we're not
184alone, or to see if we're doing right things, or to look for
185someone we can rely on. This module provides you some basic
186information on us.
187
188=head1 METHODS
189
190=head2 new
191
192creates an object and loads the subclasses you specified.
193If you don't specify any subclasses, it tries to load all
194the subclasses found just under the "Acme::CPANAuthors"
195namespace.
196
197=head2 count
198
199returns how many CPAN authors are registered.
200
201=head2 id
202
203returns all the registered ids by default. If called with an
204id, this returns if there's a registered author of the id.
205
206=head2 name
207
208returns all the registered authors' name by default. If called
209with an id, this returns the name of the author of the id.
210
211=head2 distributions, latest_distributions
212
213returns an array of Parse::CPAN::Packages::Distribution objects
214for the author of the id. See L<Parse::CPAN::Packages> for details.
215
216=head2 avatar_url
217
218returns gravatar url of the id shown at search.cpan.org.
219see L<http://site.gravatar.com/site/implement> for details.
220
221=head2 kwalitee
222
223returns kwalitee information for the author of the id.
224This information is scraped from http://kwalitee.perl.org/.
225
226=head2 look_for
227
228  my @authors = Acme::CPANAuthors->look_for('SOMEONE');
229  foreach my $author (@authors) {
230    printf "%s (%s) belongs to %s.\n",
231      $author->{id}, $author->{name}, $author->{category};
232  }
233
234takes an id or a name (or a part of them, or even an regexp)
235and returns an array of hash references, each of which contains
236an id, a name, and a basename of the class where the person is
237registered. Note that this will load all the installed
238Acme::CPANAuthors:: modules but L<Acme::CPANAuthors::Not> and
239modules with deeper namespaces.
240
241=head1 SEE ALSO
242
243As of writing this, there're more than a dozen of lists on the CPAN,
244including:
245
246=over 4
247
248=item L<Acme::CPANAuthors::Austrian>
249
250=item L<Acme::CPANAuthors::Brazilian>
251
252=item L<Acme::CPANAuthors::Canadian>
253
254=item L<Acme::CPANAuthors::Chinese>
255
256=item L<Acme::CPANAuthors::CodeRepos>
257
258=item L<Acme::CPANAuthors::French>
259
260=item L<Acme::CPANAuthors::GeekHouse>
261
262=item L<Acme::CPANAuthors::Icelandic>
263
264=item L<Acme::CPANAuthors::Israeli>
265
266=item L<Acme::CPANAuthors::Italian>
267
268=item L<Acme::CPANAuthors::Japanese>
269
270=item L<Acme::CPANAuthors::Misanthrope>
271
272=item L<Acme::CPANAuthors::Norwegian>
273
274=item L<Acme::CPANAuthors::Not>
275
276=item L<Acme::CPANAuthors::Portuguese>
277
278=item L<Acme::CPANAuthors::Russian>
279
280=item L<Acme::CPANAuthors::Taiwanese>
281
282=item L<Acme::CPANAuthors::Turkish>
283
284=item L<Acme::CPANAuthors::Ukrainian>
285
286=item L<Acme::CPANAuthors::You::re_using>
287
288=item L<Acme::CPANAuthors::Acme::CPANAuthors::Authors>
289
290=back
291
292Thank you all. And I hope more to come.
293
294=head1 AUTHOR
295
296Kenichi Ishigaki, E<lt>ishigaki at cpan.orgE<gt>
297
298=head1 COPYRIGHT AND LICENSE
299
300Copyright (C) 2007-2009 by Kenichi Ishigaki.
301
302This program is free software; you can redistribute it and/or
303modify it under the same terms as Perl itself.
304
305=cut
Note: See TracBrowser for help on using the browser.